@@ -10280,17 +10280,20 @@ static void flush_tcp_tx(struct wolfIP *s, uint64_t now)
1028010280 }
1028110281}
1028210282
10283- static void flush_udp_tx (struct wolfIP * s )
10283+ static void flush_datagram_tx (struct wolfIP * s , struct tsocket * socks ,
10284+ int count , uint8_t proto )
1028410285{
1028510286 int i ;
10286- int len ;
10287+ int is_udp = ( proto == WI_IPPROTO_UDP ) ;
1028710288
10288- for (i = 0 ; i < MAX_UDPSOCKETS ; i ++ ) {
10289- struct tsocket * t = & s -> udpsockets [i ];
10289+ for (i = 0 ; i < count ; i ++ ) {
10290+ struct tsocket * t = & socks [i ];
1029010291 struct pkt_desc * desc = fifo_peek (& t -> sock .udp .txbuf );
1029110292 int tx_drained = 0 ;
10293+ int len ;
1029210294 while (desc ) {
10293- struct wolfIP_udp_datagram * udp = (struct wolfIP_udp_datagram * )(t -> txmem + desc -> pos + sizeof (* desc ));
10295+ struct wolfIP_ip_packet * ip =
10296+ (struct wolfIP_ip_packet * )(t -> txmem + desc -> pos + sizeof (* desc ));
1029410297 unsigned int tx_if = wolfIP_socket_if_idx (t );
1029510298 int send_ret = 0 ;
1029610299#ifdef ETHERNET
@@ -10301,144 +10304,79 @@ static void flush_udp_tx(struct wolfIP *s)
1030110304 memcpy (t -> nexthop_mac , loop -> mac , 6 );
1030210305 } else if (!wolfIP_ll_is_non_ethernet (s , tx_if )) {
1030310306#ifdef IP_MULTICAST
10304- if (wolfIP_ip_is_multicast (t -> remote_ip )) {
10307+ if (is_udp && wolfIP_ip_is_multicast (t -> remote_ip )) {
1030510308 mcast_ip_to_eth (t -> remote_ip , t -> nexthop_mac );
1030610309 } else
1030710310#endif
10308- if ( (!wolfIP_ip_is_broadcast (s , nexthop ) &&
10309- ( arp_lookup (s , tx_if , nexthop , t -> nexthop_mac ) < 0 )) ) {
10310- /* Send ARP request */
10311- arp_request (s , tx_if , nexthop );
10312- break ;
10313- }
10311+ if (!wolfIP_ip_is_broadcast (s , nexthop ) &&
10312+ arp_lookup (s , tx_if , nexthop , t -> nexthop_mac ) < 0 ) {
10313+ /* Send ARP request */
10314+ arp_request (s , tx_if , nexthop );
10315+ break ;
10316+ }
1031410317 if (wolfIP_ip_is_broadcast (s , nexthop ))
1031510318 memset (t -> nexthop_mac , 0xFF , 6 );
1031610319 }
1031710320#endif
1031810321 len = desc -> len - ETH_HEADER_LEN ;
10319- ip_output_add_header (t , (struct wolfIP_ip_packet * )udp , WI_IPPROTO_UDP , len );
10320- if (wolfIP_filter_notify_udp (WOLFIP_FILT_SENDING , t -> S , tx_if , udp , desc -> len ) != 0 )
10321- break ;
10322- if (wolfIP_filter_notify_ip (WOLFIP_FILT_SENDING , t -> S , tx_if , & udp -> ip , desc -> len ) != 0 )
10322+ ip_output_add_header (t , ip , proto , len );
10323+
10324+ if (is_udp ) {
10325+ if (wolfIP_filter_notify_udp (WOLFIP_FILT_SENDING , s , tx_if ,
10326+ (struct wolfIP_udp_datagram * )ip , desc -> len ) != 0 )
10327+ break ;
10328+ } else {
10329+ if (wolfIP_filter_notify_icmp (WOLFIP_FILT_SENDING , s , tx_if ,
10330+ (struct wolfIP_icmp_packet * )ip , desc -> len ) != 0 )
10331+ break ;
10332+ }
10333+ if (wolfIP_filter_notify_ip (WOLFIP_FILT_SENDING , s , tx_if , ip , desc -> len ) != 0 )
1032310334 break ;
1032410335#ifdef ETHERNET
1032510336 if (!wolfIP_ll_is_non_ethernet (t -> S , tx_if )) {
10326- if (wolfIP_filter_notify_eth (WOLFIP_FILT_SENDING , t -> S , tx_if , & udp -> ip .eth , desc -> len ) != 0 )
10337+ if (wolfIP_filter_notify_eth (WOLFIP_FILT_SENDING , s , tx_if ,
10338+ & ip -> eth , desc -> len ) != 0 )
1032710339 break ;
1032810340 }
1032910341#endif
10330- {
10331- #ifdef DEBUG_UDP
10332- wolfIP_print_udp (udp );
10333- #endif /* DEBUG_UDP */
10334- #ifdef WOLFIP_ESP
10335- if (!wolfIP_ll_is_non_ethernet (s , tx_if )) {
10336- struct wolfIP_ll_dev * ll = wolfIP_ll_at (s , tx_if );
10337- if (esp_send (ll , (struct wolfIP_ip_packet * )udp , len ) == 1 ) {
10338- /* ipsec not configured on this interface.
10339- * send plaintext. */
10340- send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
10341- }
10342- } else {
10343- send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
10344- }
10345- #else
10346- send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
10347- #endif /* WOLFIP_ESP */
10342+ #ifdef WOLFIP_ESP
10343+ if (!wolfIP_ll_is_non_ethernet (s , tx_if )) {
10344+ struct wolfIP_ll_dev * ll = wolfIP_ll_at (s , tx_if );
10345+ /* IPsec not configured on this interface.
10346+ * Send plaintext instead.
10347+ * */
10348+ if (esp_send (ll , ip , len ) == 1 )
10349+ send_ret = wolfIP_ll_send_frame (s , tx_if , ip , desc -> len );
10350+ } else {
10351+ send_ret = wolfIP_ll_send_frame (s , tx_if , ip , desc -> len );
1034810352 }
10349- if (send_ret == - WOLFIP_EAGAIN )
10350- break ;
10351- if (send_ret < 0 )
10353+ #else
10354+ send_ret = wolfIP_ll_send_frame (s , tx_if , ip , desc -> len );
10355+ #endif
10356+ if (send_ret == - WOLFIP_EAGAIN || send_ret < 0 )
1035210357 break ;
1035310358#ifdef IP_MULTICAST
10354- /* Loopback only after a successful wire send. Running udp_try_recv
10359+ /* UDP: Loopback only after a successful wire send. Running udp_try_recv
1035510360 * before the filter/send path caused repeated local deliveries
1035610361 * when a SENDING filter blocked the frame or the driver returned
1035710362 * -EAGAIN: the descriptor stays in the txbuf and every subsequent
1035810363 * wolfIP_poll() re-enters the loop and re-loops the datagram. */
10359- if (wolfIP_ip_is_multicast (t -> remote_ip ) && t -> sock .udp .mcast_loop ) {
10360- udp_try_recv (s , tx_if , udp , desc -> len );
10361- }
10364+ if (is_udp && wolfIP_ip_is_multicast (t -> remote_ip ) && t -> sock .udp .mcast_loop )
10365+ udp_try_recv (s , tx_if , (struct wolfIP_udp_datagram * )ip , desc -> len );
1036210366#endif
1036310367 fifo_pop (& t -> sock .udp .txbuf );
1036410368 tx_drained = 1 ;
1036510369 desc = fifo_peek (& t -> sock .udp .txbuf );
1036610370 }
10367- /* Draining the txbuf frees space; raise CB_EVENT_WRITABLE so a sender
10371+ /* UDP: Draining the txbuf frees space; raise CB_EVENT_WRITABLE so a sender
1036810372 * blocked on a full buffer (e.g. the FreeRTOS BSD shim's sendto()) is
1036910373 * woken. The loopback path is handled separately via
1037010374 * wolfIP_notify_loopback_space_available(). */
10371- if (tx_drained && tx_has_writable_space (t ))
10375+ if (is_udp && tx_drained && tx_has_writable_space (t ))
1037210376 t -> events |= CB_EVENT_WRITABLE ;
1037310377 }
1037410378}
1037510379
10376- static void flush_icmp_tx (struct wolfIP * s )
10377- {
10378- int i ;
10379- int len ;
10380-
10381- for (i = 0 ; i < MAX_ICMPSOCKETS ; i ++ ) {
10382- struct tsocket * t = & s -> icmpsockets [i ];
10383- struct pkt_desc * desc = fifo_peek (& t -> sock .udp .txbuf );
10384- while (desc ) {
10385- struct wolfIP_icmp_packet * icmp = (struct wolfIP_icmp_packet * )(t -> txmem + desc -> pos + sizeof (* desc ));
10386- unsigned int tx_if = wolfIP_socket_if_idx (t );
10387- int send_ret = 0 ;
10388- #ifdef ETHERNET
10389- ip4 nexthop = wolfIP_select_nexthop_ex (s , & tx_if , t -> remote_ip );
10390- if (wolfIP_is_loopback_if (tx_if )) {
10391- struct wolfIP_ll_dev * loop = wolfIP_ll_at (s , tx_if );
10392- if (loop )
10393- memcpy (t -> nexthop_mac , loop -> mac , 6 );
10394- } else if (!wolfIP_ll_is_non_ethernet (s , tx_if )) {
10395- if ((!wolfIP_ip_is_broadcast (s , nexthop ) &&
10396- (arp_lookup (s , tx_if , nexthop , t -> nexthop_mac ) < 0 ))) {
10397- arp_request (s , tx_if , nexthop );
10398- break ;
10399- }
10400- if (wolfIP_ip_is_broadcast (s , nexthop ))
10401- memset (t -> nexthop_mac , 0xFF , 6 );
10402- }
10403- #endif
10404- len = desc -> len - ETH_HEADER_LEN ;
10405- ip_output_add_header (t , (struct wolfIP_ip_packet * )icmp , WI_IPPROTO_ICMP , len );
10406- if (wolfIP_filter_notify_icmp (WOLFIP_FILT_SENDING , t -> S , tx_if , icmp , desc -> len ) != 0 )
10407- break ;
10408- if (wolfIP_filter_notify_ip (WOLFIP_FILT_SENDING , t -> S , tx_if , & icmp -> ip , desc -> len ) != 0 )
10409- break ;
10410- #ifdef ETHERNET
10411- if (!wolfIP_ll_is_non_ethernet (t -> S , tx_if )) {
10412- if (wolfIP_filter_notify_eth (WOLFIP_FILT_SENDING , t -> S , tx_if , & icmp -> ip .eth , desc -> len ) != 0 )
10413- break ;
10414- }
10415- #endif
10416- {
10417- #ifdef WOLFIP_ESP
10418- if (!wolfIP_ll_is_non_ethernet (s , tx_if )) {
10419- struct wolfIP_ll_dev * ll = wolfIP_ll_at (s , tx_if );
10420- if (esp_send (ll , (struct wolfIP_ip_packet * )icmp , len ) == 1 ) {
10421- /* ipsec not configured on this interface.
10422- * send plaintext. */
10423- send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
10424- }
10425- } else {
10426- send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
10427- }
10428- #else
10429- send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
10430- #endif /* WOLFIP_ESP */
10431- }
10432- if (send_ret == - WOLFIP_EAGAIN )
10433- break ;
10434- if (send_ret < 0 )
10435- break ;
10436- fifo_pop (& t -> sock .udp .txbuf );
10437- desc = fifo_peek (& t -> sock .udp .txbuf );
10438- }
10439- }
10440- }
10441-
1044210380static void flush_raw_tx (struct wolfIP * s )
1044310381{
1044410382#if WOLFIP_RAWSOCKETS
@@ -10568,8 +10506,8 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
1056810506
1056910507 /* Attempt to write any pending data for all supported protocols */
1057010508 flush_tcp_tx (s , now );
10571- flush_udp_tx ( s );
10572- flush_icmp_tx ( s );
10509+ flush_datagram_tx ( s , s -> udpsockets , MAX_UDPSOCKETS , WI_IPPROTO_UDP );
10510+ flush_datagram_tx ( s , s -> icmpsockets , MAX_ICMPSOCKETS , WI_IPPROTO_ICMP );
1057310511 flush_raw_tx (s );
1057410512 flush_packet_tx (s );
1057510513
0 commit comments