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