implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) (fixes bug #35061)

This commit is contained in:
goldsimon 2011-12-17 22:12:01 +01:00
parent 8114627d6a
commit c8647c0396
7 changed files with 31 additions and 20 deletions

View File

@ -6,6 +6,10 @@ HISTORY
++ New features: ++ New features:
2011-12-17: Simon Goldschmidt
* ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW)
(fixes bug #35061)
2011-09-27: Simon Goldschmidt 2011-09-27: Simon Goldschmidt
* opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
(define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)

View File

@ -1761,7 +1761,7 @@ lwip_getsockopt_internal(void *arg)
case SO_REUSEPORT: case SO_REUSEPORT:
#endif /* SO_REUSE */ #endif /* SO_REUSE */
/*case SO_USELOOPBACK: UNIMPL */ /*case SO_USELOOPBACK: UNIMPL */
*(int*)optval = sock->conn->pcb.ip->so_options & optname; *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
s, optname, (*(int*)optval?"on":"off"))); s, optname, (*(int*)optval?"on":"off")));
break; break;
@ -2178,9 +2178,9 @@ lwip_setsockopt_internal(void *arg)
#endif /* SO_REUSE */ #endif /* SO_REUSE */
/* UNIMPL case SO_USELOOPBACK: */ /* UNIMPL case SO_USELOOPBACK: */
if (*(int*)optval) { if (*(int*)optval) {
sock->conn->pcb.ip->so_options |= optname; ip_set_option(sock->conn->pcb.ip, optname);
} else { } else {
sock->conn->pcb.ip->so_options &= ~optname; ip_reset_option(sock->conn->pcb.ip, optname);
} }
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
s, optname, (*(int*)optval?"on":"off"))); s, optname, (*(int*)optval?"on":"off")));

View File

@ -680,7 +680,7 @@ dhcp_start(struct netif *netif)
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
return ERR_MEM; return ERR_MEM;
} }
dhcp->pcb->so_options |= SOF_BROADCAST; ip_set_option(dhcp->pcb, SOF_BROADCAST);
/* set up local and remote port for the pcb */ /* set up local and remote port for the pcb */
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
@ -730,7 +730,7 @@ dhcp_inform(struct netif *netif)
return; return;
} }
dhcp.pcb = pcb; dhcp.pcb = pcb;
dhcp.pcb->so_options |= SOF_BROADCAST; ip_set_option(dhcp.pcb, SOF_BROADCAST);
udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
} }

View File

@ -110,7 +110,7 @@ raw_input(struct pbuf *p, struct netif *inp)
ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) { ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) {
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
/* broadcast filter? */ /* broadcast filter? */
if (((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp))
#if LWIP_IPV6 #if LWIP_IPV6
&& !PCB_ISIPV6(pcb) && !PCB_ISIPV6(pcb)
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
@ -279,7 +279,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
{ {
/* broadcast filter? */ /* broadcast filter? */
if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) { if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */ /* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) { if (q != p) {

View File

@ -440,7 +440,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
We do not dump TIME_WAIT pcb's; they can still be matched by incoming We do not dump TIME_WAIT pcb's; they can still be matched by incoming
packets using both local and remote IP addresses and ports to distinguish. packets using both local and remote IP addresses and ports to distinguish.
*/ */
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
} }
#endif /* SO_REUSE */ #endif /* SO_REUSE */
@ -460,8 +460,8 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
/* Omit checking for the same port if both pcbs have REUSEADDR set. /* Omit checking for the same port if both pcbs have REUSEADDR set.
For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
tcp_connect. */ tcp_connect. */
if (((pcb->so_options & SOF_REUSEADDR) == 0) || if (!ip_get_option(pcb, SOF_REUSEADDR) ||
((cpcb->so_options & SOF_REUSEADDR) == 0)) !ip_get_option(cpcb, SOF_REUSEADDR))
#endif /* SO_REUSE */ #endif /* SO_REUSE */
{ {
/* @todo: check accept_any_ip_version */ /* @todo: check accept_any_ip_version */
@ -526,7 +526,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
return pcb; return pcb;
} }
#if SO_REUSE #if SO_REUSE
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
/* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
is declared (listen-/connection-pcb), we have to make sure now that is declared (listen-/connection-pcb), we have to make sure now that
this port is only used once for every local IP. */ this port is only used once for every local IP. */
@ -550,7 +550,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
lpcb->state = LISTEN; lpcb->state = LISTEN;
lpcb->prio = pcb->prio; lpcb->prio = pcb->prio;
lpcb->so_options = pcb->so_options; lpcb->so_options = pcb->so_options;
lpcb->so_options |= SOF_ACCEPTCONN; ip_set_option(lpcb, SOF_ACCEPTCONN);
lpcb->ttl = pcb->ttl; lpcb->ttl = pcb->ttl;
lpcb->tos = pcb->tos; lpcb->tos = pcb->tos;
#if LWIP_IPV6 #if LWIP_IPV6
@ -745,7 +745,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
} }
} }
#if SO_REUSE #if SO_REUSE
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
/* Since SOF_REUSEADDR allows reusing a local address, we have to make sure /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
now that the 5-tuple is unique. */ now that the 5-tuple is unique. */
struct tcp_pcb *cpcb; struct tcp_pcb *cpcb;
@ -914,7 +914,7 @@ tcp_slowtmr_start:
} }
/* Check if KEEPALIVE should be sent */ /* Check if KEEPALIVE should be sent */
if((pcb->so_options & SOF_KEEPALIVE) && if(ip_get_option(pcb, SOF_KEEPALIVE) &&
((pcb->state == ESTABLISHED) || ((pcb->state == ESTABLISHED) ||
(pcb->state == CLOSE_WAIT))) { (pcb->state == CLOSE_WAIT))) {
if((u32_t)(tcp_ticks - pcb->tmr) > if((u32_t)(tcp_ticks - pcb->tmr) >

View File

@ -260,7 +260,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip_addr_ismulticast(ip_current_dest_addr()) || ip_addr_ismulticast(ip_current_dest_addr()) ||
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
(broadcast && (pcb->so_options & SOF_BROADCAST) && (broadcast && ip_get_option(pcb, SOF_BROADCAST) &&
(ipX_addr_isany(0, &pcb->local_ip) || (ipX_addr_isany(0, &pcb->local_ip) ||
ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) {
#else /* IP_SOF_BROADCAST_RECV */ #else /* IP_SOF_BROADCAST_RECV */
@ -365,7 +365,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip6_addr_ismulticast(ip6_current_dest_addr()) || ip6_addr_ismulticast(ip6_current_dest_addr()) ||
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
ip_addr_ismulticast(ip_current_dest_addr())) && ip_addr_ismulticast(ip_current_dest_addr())) &&
((pcb->so_options & SOF_REUSEADDR) != 0)) { ip_get_option(pcb, SOF_REUSEADDR)) {
/* pass broadcast- or multicast packets to all multicast pcbs /* pass broadcast- or multicast packets to all multicast pcbs
if SOF_REUSEADDR is set on the first match */ if SOF_REUSEADDR is set on the first match */
struct udp_pcb *mpcb; struct udp_pcb *mpcb;
@ -389,7 +389,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip_addr_ismulticast(ip_current_dest_addr()) || ip_addr_ismulticast(ip_current_dest_addr()) ||
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
(broadcast && (mpcb->so_options & SOF_BROADCAST)))))) { (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) {
#else /* IP_SOF_BROADCAST_RECV */ #else /* IP_SOF_BROADCAST_RECV */
(broadcast))))) { (broadcast))))) {
#endif /* IP_SOF_BROADCAST_RECV */ #endif /* IP_SOF_BROADCAST_RECV */
@ -632,7 +632,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
#if IP_SOF_BROADCAST #if IP_SOF_BROADCAST
/* broadcast filter? */ /* broadcast filter? */
if ( ((pcb->so_options & SOF_BROADCAST) == 0) && if (!ip_get_option(pcb, SOF_BROADCAST) &&
#if LWIP_IPV6 #if LWIP_IPV6
!PCB_ISIPV6(pcb) && !PCB_ISIPV6(pcb) &&
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
@ -900,8 +900,8 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
PCB is alread bound to, unless *all* PCBs with that port have tha PCB is alread bound to, unless *all* PCBs with that port have tha
REUSEADDR flag set. */ REUSEADDR flag set. */
#if SO_REUSE #if SO_REUSE
else if (((pcb->so_options & SOF_REUSEADDR) == 0) && else if (!ip_get_option(pcb, SOF_REUSEADDR) &&
((ipcb->so_options & SOF_REUSEADDR) == 0)) { !ip_get_option(ipcb, SOF_REUSEADDR)) {
#else /* SO_REUSE */ #else /* SO_REUSE */
/* port matches that of PCB in list and REUSEADDR not set -> reject */ /* port matches that of PCB in list and REUSEADDR not set -> reject */
else { else {

View File

@ -197,6 +197,13 @@ extern struct ip_globals ip_data;
/** Union destination address of current_header */ /** Union destination address of current_header */
#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) #define ipX_current_dest_addr() (&ip_data.current_iphdr_dest)
/** Gets an IP pcb option (SOF_* flags) */
#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt))
/** Sets an IP pcb option (SOF_* flags) */
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
/** Resets an IP pcb option (SOF_* flags) */
#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
#if LWIP_IPV6 #if LWIP_IPV6
#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ #define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \
((isipv6) ? \ ((isipv6) ? \