@@ -825,88 +825,80 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short
825
825
for (sal = psal ; !fatal && * sal != NULL ; sal ++ ) {
826
826
sa = * sal ;
827
827
828
- /* create a socket for this address */
829
- sock = socket (sa -> sa_family , socktype , 0 );
830
-
831
- if (sock == SOCK_ERR ) {
832
- continue ;
833
- }
834
-
835
828
switch (sa -> sa_family ) {
836
829
#if HAVE_GETADDRINFO && HAVE_IPV6
837
830
case AF_INET6 :
838
831
if (!bindto || strchr (bindto , ':' )) {
839
- ((struct sockaddr_in6 * )sa )-> sin6_family = sa -> sa_family ;
840
832
((struct sockaddr_in6 * )sa )-> sin6_port = htons (port );
841
833
socklen = sizeof (struct sockaddr_in6 );
842
834
} else {
843
- socklen = 0 ;
844
- sa = NULL ;
835
+ /* Expect IPV4 address, skip to the next */
836
+ continue ;
845
837
}
846
838
break ;
847
839
#endif
848
840
case AF_INET :
849
- ((struct sockaddr_in * )sa )-> sin_family = sa -> sa_family ;
850
841
((struct sockaddr_in * )sa )-> sin_port = htons (port );
851
842
socklen = sizeof (struct sockaddr_in );
843
+ if (bindto && strchr (bindto , ':' )) {
844
+ /* IPV4 sock can not bind to IPV6 address */
845
+ bindto = NULL ;
846
+ }
852
847
break ;
853
848
default :
854
- /* Unknown family */
855
- socklen = 0 ;
856
- sa = NULL ;
849
+ /* Unsupported family, skip to the next */
850
+ continue ;
851
+ }
852
+
853
+ /* create a socket for this address */
854
+ sock = socket (sa -> sa_family , socktype , 0 );
855
+
856
+ if (sock == SOCK_ERR ) {
857
+ continue ;
857
858
}
858
859
859
860
if (sa ) {
860
861
/* make a connection attempt */
861
862
862
863
if (bindto ) {
863
- struct sockaddr * local_address = NULL ;
864
- int local_address_len = 0 ;
864
+ struct {
865
+ int len ;
866
+ union {
867
+ struct sockaddr common ;
868
+ struct sockaddr_in in4 ;
869
+ #if HAVE_IPV6 && HAVE_INET_PTON
870
+ struct sockaddr_in6 in6 ;
871
+ #endif
872
+ };
873
+ } local_address ;
865
874
875
+ local_address .len = 0 ;
866
876
if (sa -> sa_family == AF_INET ) {
867
- if (strchr (bindto ,':' )) {
868
- goto skip_bind ;
869
- }
870
- struct sockaddr_in * in4 = emalloc (sizeof (struct sockaddr_in ));
871
-
872
- local_address = (struct sockaddr * )in4 ;
873
- local_address_len = sizeof (struct sockaddr_in );
874
-
875
- in4 -> sin_family = sa -> sa_family ;
876
- in4 -> sin_port = htons (bindport );
877
877
#ifdef HAVE_INET_PTON
878
- if (! inet_pton (AF_INET , bindto , & in4 -> sin_addr )) {
878
+ if (inet_pton (AF_INET , bindto , & local_address . in4 . sin_addr ) == 1 ) {
879
879
#else
880
- if (! inet_aton (bindto , & in4 -> sin_addr )) {
880
+ if (inet_aton (bindto , & local_address . in4 . sin_addr )) {
881
881
#endif
882
- php_error_docref (NULL , E_WARNING , "Invalid IP Address: %s" , bindto );
883
- goto skip_bind ;
882
+ local_address .len = sizeof (struct sockaddr_in );
883
+ local_address .in4 .sin_family = sa -> sa_family ;
884
+ local_address .in4 .sin_port = htons (bindport );
885
+ memset (& (local_address .in4 .sin_zero ), 0 , sizeof (local_address .in4 .sin_zero ));
884
886
}
885
- memset (& (in4 -> sin_zero ), 0 , sizeof (in4 -> sin_zero ));
886
887
}
887
888
#if HAVE_IPV6 && HAVE_INET_PTON
888
- else { /* IPV6 */
889
- struct sockaddr_in6 * in6 = emalloc (sizeof (struct sockaddr_in6 ));
890
-
891
- local_address = (struct sockaddr * )in6 ;
892
- local_address_len = sizeof (struct sockaddr_in6 );
893
-
894
- in6 -> sin6_family = sa -> sa_family ;
895
- in6 -> sin6_port = htons (bindport );
896
- if (inet_pton (AF_INET6 , bindto , & in6 -> sin6_addr ) < 1 ) {
897
- php_error_docref (NULL , E_WARNING , "Invalid IP Address: %s" , bindto );
898
- goto skip_bind ;
889
+ else { /* IPV6 */
890
+ if (inet_pton (AF_INET6 , bindto , & local_address .in6 .sin6_addr ) == 1 ) {
891
+ local_address .len = sizeof (struct sockaddr_in6 );
892
+ local_address .in6 .sin6_family = sa -> sa_family ;
893
+ local_address .in6 .sin6_port = htons (bindport );
899
894
}
900
895
}
901
896
#endif
902
-
903
- if (!local_address || bind (sock , local_address , local_address_len )) {
897
+ if (local_address .len == 0 ) {
898
+ php_error_docref (NULL , E_WARNING , "Invalid IP Address: %s" , bindto );
899
+ } else if (bind (sock , & local_address .common , local_address .len )) {
904
900
php_error_docref (NULL , E_WARNING , "Failed to bind to '%s:%d', system said: %s" , bindto , bindport , strerror (errno ));
905
901
}
906
- skip_bind :
907
- if (local_address ) {
908
- efree (local_address );
909
- }
910
902
}
911
903
/* free error string received during previous iteration (if any) */
912
904
if (error_string && * error_string ) {
0 commit comments