@@ -1003,26 +1003,23 @@ resolve_addrinfo_for_socket(net_socket_impl_t *net_socket,
10031003 avs_net_af_t socket_family =
10041004 get_avs_af (get_socket_family (net_socket -> socket ));
10051005 if (socket_family != AVS_NET_AF_UNSPEC && socket_family != family ) {
1006- # if defined( AVS_COMMONS_NET_WITH_IPV4 ) && defined( AVS_COMMONS_NET_WITH_IPV6 )
1006+ # ifdef WITH_AVS_V4MAPPED
10071007 if (socket_family == AVS_NET_AF_INET6 ) {
1008- # ifdef WITH_AVS_V4MAPPED
10091008 // If we have an already created socket that is bound to IPv6,
10101009 // but the requested family is something else, use v4-mapping
10111010 resolve_flags |= AVS_NET_ADDRINFO_RESOLVE_F_V4MAPPED ;
1012- # else // WITH_AVS_V4MAPPED
1011+ } else
1012+ # endif // WITH_AVS_V4MAPPED
1013+ {
1014+ // The case when we have an already created socket, we cannot
1015+ // use IPv6-to-IPv4 mapping, and the requested family is
1016+ // different from the socket's bound one will be handled in
1017+ // try_connect() and ensure_socket_bound_to_family()
10131018 if (!for_connect ) {
1014- // We shouldn't recreate the socket for sendto, just give up
1019+ // ...but we shouldn't recreate the socket for sendto, so
1020+ // just give up in that case
10151021 return NULL ;
10161022 }
1017- # endif // WITH_AVS_V4MAPPED
1018- } else
1019- # endif // defined(AVS_COMMONS_NET_WITH_IPV4) &&
1020- // defined(AVS_COMMONS_NET_WITH_IPV6)
1021- {
1022- // If we have an already created socket, we cannot use
1023- // IPv6-to-IPv4 mapping, and the requested family is different
1024- // than the socket's bound one - we're screwed, just give up
1025- return NULL ;
10261023 }
10271024 }
10281025 }
@@ -1135,9 +1132,7 @@ static avs_error_t create_listening_socket(net_socket_impl_t *net_socket,
11351132 return err ;
11361133}
11371134
1138- # if defined(AVS_COMMONS_NET_WITH_IPV4 ) \
1139- && defined(AVS_COMMONS_NET_WITH_IPV6 ) \
1140- && !defined(WITH_AVS_V4MAPPED )
1135+ # if defined(AVS_COMMONS_NET_WITH_IPV4 ) && defined(AVS_COMMONS_NET_WITH_IPV6 )
11411136static avs_error_t
11421137ensure_socket_bound_to_family (net_socket_impl_t * net_socket ,
11431138 const sockaddr_endpoint_union_t * target_address ) {
@@ -1182,23 +1177,21 @@ ensure_socket_bound_to_family(net_socket_impl_t *net_socket,
11821177 return create_listening_socket (net_socket , & new_addr .addr , new_addr_len );
11831178}
11841179# endif // defined(AVS_COMMONS_NET_WITH_IPV4) &&
1185- // defined(AVS_COMMONS_NET_WITH_IPV6) && !defined(WITH_AVS_V4MAPPED)
1180+ // defined(AVS_COMMONS_NET_WITH_IPV6)
11861181
11871182static avs_error_t try_connect (net_socket_impl_t * net_socket ,
11881183 const sockaddr_endpoint_union_t * address ) {
11891184 char socket_was_already_open = (net_socket -> socket != INVALID_SOCKET );
11901185 avs_error_t err = AVS_OK ;
1191- # if defined(AVS_COMMONS_NET_WITH_IPV4 ) \
1192- && defined(AVS_COMMONS_NET_WITH_IPV6 ) \
1193- && !defined(WITH_AVS_V4MAPPED )
1186+ # if defined(AVS_COMMONS_NET_WITH_IPV4 ) && defined(AVS_COMMONS_NET_WITH_IPV6 )
11941187 if (socket_was_already_open && net_socket -> type == AVS_NET_UDP_SOCKET ) {
11951188 err = ensure_socket_bound_to_family (net_socket , address );
11961189 if (avs_is_err (err )) {
11971190 return err ;
11981191 }
11991192 }
12001193# endif // defined(AVS_COMMONS_NET_WITH_IPV4) &&
1201- // defined(AVS_COMMONS_NET_WITH_IPV6) && !defined(WITH_AVS_V4MAPPED)
1194+ // defined(AVS_COMMONS_NET_WITH_IPV6)
12021195 if (!socket_was_already_open ) {
12031196 if ((net_socket -> socket =
12041197 socket (address -> sockaddr_ep .addr .sa_family ,
@@ -2056,6 +2049,14 @@ static avs_error_t get_opt_net(avs_net_socket_t *net_socket_,
20562049 case AVS_NET_SOCKET_HAS_BUFFERED_DATA :
20572050 out_option_value -> flag = false;
20582051 return AVS_OK ;
2052+ case AVS_NET_SOCKET_OPT_PREFERRED_ADDR_FAMILY :
2053+ out_option_value -> addr_family =
2054+ net_socket -> configuration .preferred_family ;
2055+ return AVS_OK ;
2056+ case AVS_NET_SOCKET_OPT_FORCED_ADDR_FAMILY :
2057+ out_option_value -> addr_family =
2058+ net_socket -> configuration .address_family ;
2059+ return AVS_OK ;
20592060 default :
20602061 LOG (DEBUG ,
20612062 _ ("get_opt_net: unknown or unsupported option key: " )
@@ -2065,6 +2066,17 @@ static avs_error_t get_opt_net(avs_net_socket_t *net_socket_,
20652066 }
20662067}
20672068
2069+ static bool is_valid_addr_family (avs_net_af_t family ) {
2070+ return family == AVS_NET_AF_UNSPEC
2071+ # ifdef AVS_COMMONS_NET_WITH_IPV4
2072+ || family == AVS_NET_AF_INET4
2073+ # endif /* AVS_COMMONS_NET_WITH_IPV4 */
2074+ # ifdef AVS_COMMONS_NET_WITH_IPV6
2075+ || family == AVS_NET_AF_INET6
2076+ # endif /* AVS_COMMONS_NET_WITH_IPV6 */
2077+ ;
2078+ }
2079+
20682080static avs_error_t set_opt_net (avs_net_socket_t * net_socket_ ,
20692081 avs_net_socket_opt_key_t option_key ,
20702082 avs_net_socket_opt_value_t option_value ) {
@@ -2073,6 +2085,23 @@ static avs_error_t set_opt_net(avs_net_socket_t *net_socket_,
20732085 case AVS_NET_SOCKET_OPT_RECV_TIMEOUT :
20742086 net_socket -> recv_timeout = option_value .recv_timeout ;
20752087 return AVS_OK ;
2088+ case AVS_NET_SOCKET_OPT_PREFERRED_ADDR_FAMILY :
2089+ if (!is_valid_addr_family (option_value .addr_family )) {
2090+ LOG (DEBUG , _ ("set_opt_net: unsupported preferred address family" ));
2091+ return avs_errno (AVS_EINVAL );
2092+ } else {
2093+ net_socket -> configuration .preferred_family =
2094+ option_value .addr_family ;
2095+ return AVS_OK ;
2096+ }
2097+ case AVS_NET_SOCKET_OPT_FORCED_ADDR_FAMILY :
2098+ if (!is_valid_addr_family (option_value .addr_family )) {
2099+ LOG (DEBUG , _ ("set_opt_net: unsupported forced address family" ));
2100+ return avs_errno (AVS_EINVAL );
2101+ } else {
2102+ net_socket -> configuration .address_family = option_value .addr_family ;
2103+ return AVS_OK ;
2104+ }
20762105 default :
20772106 LOG (DEBUG ,
20782107 _ ("set_opt_net: unknown or unsupported option key: " )
0 commit comments