Added new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to more than one pcb

This commit is contained in:
goldsimon 2010-05-15 14:52:39 +00:00
parent baeb41f5f4
commit a56795c149
3 changed files with 55 additions and 2 deletions

View File

@ -14,7 +14,9 @@ HISTORY
++ New features:
2010-05-13: Simon Goldschmidt
* tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly)
* tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added
new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast
packets to more than one pcb.
2010-05-02: Simon Goldschmidt
* netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending

View File

@ -276,6 +276,48 @@ udp_input(struct pbuf *p, struct netif *inp)
}
if (pcb != NULL) {
snmp_inc_udpindatagrams();
#if SO_REUSE_RXTOALL
if ((broadcast || ip_addr_ismulticast(&iphdr->dest)) &&
((pcb->so_options & SOF_REUSEADDR) != 0)) {
/* pass broadcast- or multicast packets to all multicast pcbs
if SOF_REUSEADDR is set on the first match */
struct udp_pcb *mpcb;
/* for that, move payload to IP header again */
pbuf_header(p, (s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
if (mpcb != pcb) {
/* compare PCB local addr+port to UDP destination addr+port */
if ((mpcb->local_port == dest) &&
((!broadcast && ip_addr_isany(&mpcb->local_ip)) ||
ip_addr_cmp(&(mpcb->local_ip), &(iphdr->dest)) ||
#if LWIP_IGMP
ip_addr_ismulticast(&(iphdr->dest)) ||
#endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV
(broadcast && (mpcb->so_options & SOF_BROADCAST)))) {
#else /* IP_SOF_BROADCAST_RECV */
(broadcast))) {
#endif /* IP_SOF_BROADCAST_RECV */
/* pass a copy of the packet to all local matches */
if (mpcb->recv != NULL) {
struct pbuf *q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
if (q != NULL) {
err_t err = pbuf_copy(q, p);
if (err == ERR_OK) {
/* move payload to UDP data */
struct ip_hdr *q_iphdr = (struct ip_hdr *)q->payload;
pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
mpcb->recv(mpcb->recv_arg, mpcb, q, &q_iphdr->src, src);
}
}
}
}
}
}
/* and move payload to UDP data again */
pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
}
#endif /* SO_REUSE_RXTOALL */
/* callback */
if (pcb->recv != NULL) {
/* now the recv function is responsible for freeing p */

View File

@ -1388,12 +1388,21 @@
#endif
/**
* SO_REUSE==1: Enable SO_REUSEADDR and SO_REUSEPORT options. DO NOT USE!
* SO_REUSE==1: Enable SO_REUSEADDR option.
*/
#ifndef SO_REUSE
#define SO_REUSE 0
#endif
/**
* SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets
* to all local matches if SO_REUSEADDR is turned on.
* WARNING: Adds a memcpy for every packet if passing to more than one pcb!
*/
#ifndef SO_REUSE_RXTOALL
#define SO_REUSE_RXTOALL 0
#endif
/*
----------------------------------------
---------- Statistics options ----------