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