raw: extend support for connected sockets

The support for connecting raw sockets is extended to match the
support for UDP sockets, while keeping the current API unchanged:

- for connected sockets, filter incoming packets on source address;
- use a flag to indicate whether a socket is connected, at no extra
  memory cost; the application may check this flag if needed;
- added raw_disconnect(), which so far existed in documentation only.
This commit is contained in:
David van Moolenbroek 2017-01-04 22:23:29 +00:00 committed by Dirk Ziegelmeier
parent 52f448978f
commit aea7062223
2 changed files with 34 additions and 2 deletions

View File

@ -65,7 +65,7 @@
static struct raw_pcb *raw_pcbs;
static u8_t
raw_input_match(struct raw_pcb *pcb, u8_t broadcast)
raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast)
{
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
@ -157,7 +157,9 @@ raw_input(struct pbuf *p, struct netif *inp)
/* loop through all raw pcbs until the packet is eaten by one */
/* this allows multiple pcbs to match against the packet by design */
while ((eaten == 0) && (pcb != NULL)) {
if ((pcb->protocol == proto) && raw_input_match(pcb, broadcast)) {
if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
(((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
/* receive callback function available? */
if (pcb->recv != NULL) {
#ifndef LWIP_NOASSERT
@ -237,9 +239,33 @@ raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
return ERR_VAL;
}
ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
pcb->flags |= RAW_FLAGS_CONNECTED;
return ERR_OK;
}
/**
* @ingroup raw_raw
* Disconnect a RAW PCB.
*
* @param pcb the raw pcb to disconnect.
*/
void
raw_disconnect(struct raw_pcb *pcb)
{
/* reset remote address association */
#if LWIP_IPV4 && LWIP_IPV6
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);
} else {
#endif
ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);
#if LWIP_IPV4 && LWIP_IPV6
}
#endif
/* mark PCB as unconnected */
pcb->flags &= ~RAW_FLAGS_CONNECTED;
}
/**
* @ingroup raw_raw
* Set the callback function for received packets that match the

View File

@ -52,6 +52,8 @@
extern "C" {
#endif
#define RAW_FLAGS_CONNECTED 0x01U
struct raw_pcb;
/** Function prototype for raw pcb receive callback functions.
@ -75,6 +77,7 @@ struct raw_pcb {
struct raw_pcb *next;
u8_t protocol;
u8_t flags;
/** receive callback function */
raw_recv_fn recv;
@ -94,12 +97,15 @@ struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto);
void raw_remove (struct raw_pcb *pcb);
err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
void raw_disconnect (struct raw_pcb *pcb);
err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr);
err_t raw_send (struct raw_pcb *pcb, struct pbuf *p);
void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg);
#define raw_flags(pcb) ((pcb)->flags)
/* The following functions are the lower layer interface to RAW. */
u8_t raw_input (struct pbuf *p, struct netif *inp);
#define raw_init() /* Compatibility define, no init needed. */