@@ -228,6 +228,39 @@ sport_destroy (struct service_port *sport)
228228}
229229
230230
231+ static char *
232+ sockaddr2str (const struct sockaddr * addr , char * buf , size_t sz )
233+ {
234+ unsigned short port ;
235+ int len ;
236+
237+ switch (addr -> sa_family )
238+ {
239+ case AF_INET :
240+ port = ntohs (((struct sockaddr_in * ) addr )-> sin_port );
241+ if (!inet_ntop (AF_INET , & ((struct sockaddr_in * ) addr )-> sin_addr ,
242+ buf , sz ))
243+ buf [0 ] = '\0' ;
244+ break ;
245+ case AF_INET6 :
246+ port = ntohs (((struct sockaddr_in6 * ) addr )-> sin6_port );
247+ if (!inet_ntop (AF_INET6 , & ((struct sockaddr_in6 * ) addr )-> sin6_addr ,
248+ buf , sz ))
249+ buf [0 ] = '\0' ;
250+ break ;
251+ default :
252+ port = 0 ;
253+ (void ) snprintf (buf , sz , "<invalid family %d>" , addr -> sa_family );
254+ break ;
255+ }
256+
257+ len = strlen (buf );
258+ if (len < (int ) sz )
259+ snprintf (buf + len , sz - (size_t ) len , ":%hu" , port );
260+ return buf ;
261+ }
262+
263+
231264struct service_port *
232265sport_new (const char * optarg , struct prog * prog )
233266{
@@ -600,6 +633,14 @@ read_one_packet (struct read_iter *iter)
600633 sport -> drop_init = 1 ;
601634 sport -> n_dropped = n_dropped ;
602635#endif
636+ char localaddr_str [80 ];
637+ char remoteaddr_str [80 ];
638+ LSQ_DEBUG ("[%s] RX packet %zd bytes from: %s" ,
639+ sockaddr2str ((struct sockaddr * )local_addr , localaddr_str ,
640+ sizeof (localaddr_str )),
641+ nread , sockaddr2str (
642+ (struct sockaddr * )& packs_in -> peer_addresses [iter -> ri_idx ],
643+ remoteaddr_str , sizeof (remoteaddr_str )));
603644
604645#ifndef WIN32
605646 packs_in -> vecs [iter -> ri_idx ].iov_len = nread ;
@@ -1557,7 +1598,6 @@ send_packets_using_sendmmsg (const struct lsquic_out_spec *specs,
15571598#endif
15581599
15591600
1560- #if LSQUIC_PREFERRED_ADDR
15611601static const struct service_port *
15621602find_sport (struct prog * prog , const struct sockaddr * local_sa )
15631603{
@@ -1574,6 +1614,17 @@ find_sport (struct prog *prog, const struct sockaddr *local_sa)
15741614 : sizeof (struct sockaddr_in6 );
15751615 if (0 == memcmp (addr , local_sa , len ))
15761616 return sport ;
1617+ if (((struct sockaddr_in * )addr )-> sin_port ==
1618+ ((struct sockaddr_in * )local_sa )-> sin_port )
1619+ {
1620+ if ((addr -> sa_family == AF_INET
1621+ && ((struct sockaddr_in * )addr )-> sin_addr .s_addr
1622+ == INADDR_ANY )
1623+ || (addr -> sa_family == AF_INET6
1624+ && (IN6_IS_ADDR_UNSPECIFIED (
1625+ & ((struct sockaddr_in6 * )addr )-> sin6_addr ))))
1626+ return sport ;
1627+ }
15771628 }
15781629 }
15791630
@@ -1582,9 +1633,6 @@ find_sport (struct prog *prog, const struct sockaddr *local_sa)
15821633}
15831634
15841635
1585- #endif
1586-
1587-
15881636static int
15891637send_packets_one_by_one (const struct lsquic_out_spec * specs , unsigned count )
15901638{
@@ -1655,10 +1703,8 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
16551703 do
16561704 {
16571705 sport = specs [n ].peer_ctx ;
1658- #if LSQUIC_PREFERRED_ADDR
16591706 if (sport -> sp_prog -> prog_flags & PROG_SEARCH_ADDRS )
16601707 sport = find_sport (sport -> sp_prog , specs [n ].local_sa );
1661- #endif
16621708#ifndef WIN32
16631709 msg .msg_name = (void * ) specs [n ].dest_sa ;
16641710 msg .msg_namelen = (AF_INET == specs [n ].dest_sa -> sa_family ?
@@ -1734,6 +1780,14 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
17341780#endif
17351781 break ;
17361782 }
1783+ char localaddr_str [80 ];
1784+ char remoteaddr_str [80 ];
1785+ LSQ_DEBUG ("[%s] TX packet %d bytes to: %s" ,
1786+ sockaddr2str ((struct sockaddr * )& sport -> sp_local_addr ,
1787+ localaddr_str , sizeof (localaddr_str )),
1788+ s , sockaddr2str (specs [n ].dest_sa ,
1789+ remoteaddr_str , sizeof (remoteaddr_str )));
1790+
17371791 ++ n ;
17381792 }
17391793 while (n < count );
@@ -1779,6 +1833,47 @@ sport_packets_out (void *ctx, const struct lsquic_out_spec *specs,
17791833}
17801834
17811835
1836+ int
1837+ set_perferred_address (uint8_t * addr , uint16_t * port , const char * s , int family )
1838+ {
1839+ char addr_buf [1024 ];
1840+ const char * colon ;
1841+ if (s && strlen (s ) < sizeof (addr_buf ) && (colon = strrchr (s , ':' )))
1842+ {
1843+ strncpy (addr_buf , s , colon - s );
1844+ addr_buf [colon - s ] = '\0' ;
1845+ if (inet_pton (family , addr_buf , addr ))
1846+ {
1847+ * port = atoi (colon + 1 );
1848+ //params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
1849+ return 1 ;
1850+ }
1851+ else
1852+ {
1853+ struct addrinfo hints , * res = NULL ;
1854+ int ret ;
1855+ memset (& hints , 0 , sizeof (hints ));
1856+ hints .ai_flags = AI_NUMERICSERV ;
1857+ hints .ai_family = family ;
1858+ ret = getaddrinfo (addr_buf , colon + 1 , & hints , & res );
1859+ if (ret != 0 )
1860+ {
1861+ LSQ_ERROR ("could not resolve %s:%s: %s" , addr_buf , colon + 1 ,
1862+ gai_strerror (ret ));
1863+ return 0 ;
1864+ }
1865+ if (family == AF_INET )
1866+ memcpy (addr , & ((struct sockaddr_in * )res -> ai_addr )-> sin_addr .s_addr , 4 );
1867+ else
1868+ memcpy (addr , & ((struct sockaddr_in6 * )res -> ai_addr )-> sin6_addr , 16 );
1869+ * port = atoi (colon + 1 );
1870+ return 1 ;
1871+ }
1872+ }
1873+ return 0 ;
1874+ }
1875+
1876+
17821877int
17831878set_engine_option (struct lsquic_engine_settings * settings ,
17841879 int * version_cleared , const char * name )
@@ -1981,6 +2076,20 @@ set_engine_option (struct lsquic_engine_settings *settings,
19812076 settings -> es_delayed_acks = atoi (val );
19822077 return 0 ;
19832078 }
2079+ if (0 == strncmp (name , "preferred_v4" , 12 ))
2080+ {
2081+ set_perferred_address (settings -> es_preferred_address ,
2082+ (uint16_t * )& settings -> es_preferred_address [4 ], val , AF_INET );
2083+ return 0 ;
2084+ }
2085+ if (0 == strncmp (name , "preferred_v6" , 12 ))
2086+ {
2087+ set_perferred_address (& settings -> es_preferred_address [6 ],
2088+ (uint16_t * )& settings -> es_preferred_address [22 ],
2089+ val , AF_INET6 );
2090+ return 0 ;
2091+ }
2092+
19842093 break ;
19852094 case 13 :
19862095 if (0 == strncmp (name , "support_tcid0" , 13 ))
0 commit comments