@@ -430,69 +430,64 @@ 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 ;
457
447
}
458
448
459
- if (sa ) {
460
- /* attempt to bind */
449
+ /* create a socket for this address */
450
+ sock = socket (sa -> sa_family , socktype , 0 );
451
+
452
+ if (sock == SOCK_ERR ) {
453
+ continue ;
454
+ }
455
+
456
+ /* attempt to bind */
461
457
462
458
#ifdef SO_REUSEADDR
463
- setsockopt (sock , SOL_SOCKET , SO_REUSEADDR , (char * )& sockoptval , sizeof (sockoptval ));
459
+ setsockopt (sock , SOL_SOCKET , SO_REUSEADDR , (char * )& sockoptval , sizeof (sockoptval ));
464
460
#endif
465
461
#ifdef IPV6_V6ONLY
466
- if (sockopts & STREAM_SOCKOP_IPV6_V6ONLY ) {
467
- int ipv6_val = !!(sockopts & STREAM_SOCKOP_IPV6_V6ONLY_ENABLED );
468
- setsockopt (sock , IPPROTO_IPV6 , IPV6_V6ONLY , (char * )& ipv6_val , sizeof (sockoptval ));
469
- }
462
+ if (sockopts & STREAM_SOCKOP_IPV6_V6ONLY ) {
463
+ int ipv6_val = !!(sockopts & STREAM_SOCKOP_IPV6_V6ONLY_ENABLED );
464
+ setsockopt (sock , IPPROTO_IPV6 , IPV6_V6ONLY , (char * )& ipv6_val , sizeof (sockoptval ));
465
+ }
470
466
#endif
471
467
#ifdef SO_REUSEPORT
472
- if (sockopts & STREAM_SOCKOP_SO_REUSEPORT ) {
473
- setsockopt (sock , SOL_SOCKET , SO_REUSEPORT , (char * )& sockoptval , sizeof (sockoptval ));
474
- }
468
+ if (sockopts & STREAM_SOCKOP_SO_REUSEPORT ) {
469
+ setsockopt (sock , SOL_SOCKET , SO_REUSEPORT , (char * )& sockoptval , sizeof (sockoptval ));
470
+ }
475
471
#endif
476
472
#ifdef SO_BROADCAST
477
- if (sockopts & STREAM_SOCKOP_SO_BROADCAST ) {
478
- setsockopt (sock , SOL_SOCKET , SO_BROADCAST , (char * )& sockoptval , sizeof (sockoptval ));
479
- }
473
+ if (sockopts & STREAM_SOCKOP_SO_BROADCAST ) {
474
+ setsockopt (sock , SOL_SOCKET , SO_BROADCAST , (char * )& sockoptval , sizeof (sockoptval ));
475
+ }
480
476
#endif
481
477
#ifdef TCP_NODELAY
482
- if (sockopts & STREAM_SOCKOP_TCP_NODELAY ) {
483
- setsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& sockoptval , sizeof (sockoptval ));
484
- }
478
+ if (sockopts & STREAM_SOCKOP_TCP_NODELAY ) {
479
+ setsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& sockoptval , sizeof (sockoptval ));
480
+ }
485
481
#endif
486
482
487
- n = bind (sock , sa , socklen );
488
-
489
- if (n != SOCK_CONN_ERR ) {
490
- goto bound ;
491
- }
483
+ n = bind (sock , sa , socklen );
492
484
493
- err = php_socket_errno ();
485
+ if (n != SOCK_CONN_ERR ) {
486
+ goto bound ;
494
487
}
495
488
489
+ err = php_socket_errno ();
490
+
496
491
closesocket (sock );
497
492
}
498
493
sock = -1 ;
@@ -825,148 +820,135 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short
825
820
for (sal = psal ; !fatal && * sal != NULL ; sal ++ ) {
826
821
sa = * sal ;
827
822
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
823
switch (sa -> sa_family ) {
836
824
#if HAVE_GETADDRINFO && HAVE_IPV6
837
825
case AF_INET6 :
838
826
if (!bindto || strchr (bindto , ':' )) {
839
- ((struct sockaddr_in6 * )sa )-> sin6_family = sa -> sa_family ;
840
827
((struct sockaddr_in6 * )sa )-> sin6_port = htons (port );
841
828
socklen = sizeof (struct sockaddr_in6 );
842
829
} else {
843
- socklen = 0 ;
844
- sa = NULL ;
830
+ /* Expect IPV4 address, skip to the next */
831
+ continue ;
845
832
}
846
833
break ;
847
834
#endif
848
835
case AF_INET :
849
- ((struct sockaddr_in * )sa )-> sin_family = sa -> sa_family ;
850
836
((struct sockaddr_in * )sa )-> sin_port = htons (port );
851
837
socklen = sizeof (struct sockaddr_in );
838
+ if (bindto && strchr (bindto , ':' )) {
839
+ /* IPV4 sock can not bind to IPV6 address */
840
+ bindto = NULL ;
841
+ }
852
842
break ;
853
843
default :
854
- /* Unknown family */
855
- socklen = 0 ;
856
- sa = NULL ;
844
+ /* Unsupported family, skip to the next */
845
+ continue ;
857
846
}
858
847
859
- if ( sa ) {
860
- /* make a connection attempt */
848
+ /* create a socket for this address */
849
+ sock = socket ( sa -> sa_family , socktype , 0 );
861
850
862
- if (bindto ) {
863
- struct sockaddr * local_address = NULL ;
864
- int local_address_len = 0 ;
851
+ if (sock == SOCK_ERR ) {
852
+ continue ;
853
+ }
865
854
866
- 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 ));
855
+ /* make a connection attempt */
871
856
872
- local_address = (struct sockaddr * )in4 ;
873
- local_address_len = sizeof (struct sockaddr_in );
857
+ if (bindto ) {
858
+ union {
859
+ struct sockaddr common ;
860
+ struct sockaddr_in in4 ;
861
+ #if HAVE_IPV6 && HAVE_INET_PTON
862
+ struct sockaddr_in6 in6 ;
863
+ #endif
864
+ } local_address ;
865
+ int local_address_len = 0 ;
874
866
875
- in4 -> sin_family = sa -> sa_family ;
876
- in4 -> sin_port = htons (bindport );
867
+ if (sa -> sa_family == AF_INET ) {
877
868
#ifdef HAVE_INET_PTON
878
- if (! inet_pton (AF_INET , bindto , & in4 -> sin_addr )) {
869
+ if (inet_pton (AF_INET , bindto , & local_address . in4 . sin_addr ) == 1 ) {
879
870
#else
880
- if (! inet_aton (bindto , & in4 -> sin_addr )) {
871
+ if (inet_aton (bindto , & local_address . in4 . sin_addr )) {
881
872
#endif
882
- php_error_docref ( NULL , E_WARNING , "Invalid IP Address: %s" , bindto );
883
- goto skip_bind ;
884
- }
885
- memset (& (in4 -> sin_zero ), 0 , sizeof (in4 -> sin_zero ));
873
+ local_address_len = sizeof ( struct sockaddr_in );
874
+ local_address . in4 . sin_family = sa -> sa_family ;
875
+ local_address . in4 . sin_port = htons ( bindport );
876
+ memset (& (local_address . in4 . sin_zero ), 0 , sizeof (local_address . in4 . sin_zero ));
886
877
}
878
+ }
887
879
#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 ;
880
+ else { /* IPV6 */
881
+ if (inet_pton (AF_INET6 , bindto , & local_address .in6 .sin6_addr ) == 1 ) {
892
882
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 ;
899
- }
900
- }
901
- #endif
902
-
903
- if (!local_address || bind (sock , local_address , local_address_len )) {
904
- php_error_docref (NULL , E_WARNING , "Failed to bind to '%s:%d', system said: %s" , bindto , bindport , strerror (errno ));
905
- }
906
- skip_bind :
907
- if (local_address ) {
908
- efree (local_address );
883
+ local_address .in6 .sin6_family = sa -> sa_family ;
884
+ local_address .in6 .sin6_port = htons (bindport );
909
885
}
910
886
}
911
- /* free error string received during previous iteration (if any) */
912
- if (error_string && * error_string ) {
913
- zend_string_release_ex (* error_string , 0 );
914
- * error_string = NULL ;
887
+ #endif
888
+ if (local_address_len == 0 ) {
889
+ php_error_docref (NULL , E_WARNING , "Invalid IP Address: %s" , bindto );
890
+ } else if (bind (sock , & local_address .common , local_address_len )) {
891
+ php_error_docref (NULL , E_WARNING , "Failed to bind to '%s:%d', system said: %s" , bindto , bindport , strerror (errno ));
915
892
}
893
+ }
894
+ /* free error string received during previous iteration (if any) */
895
+ if (error_string && * error_string ) {
896
+ zend_string_release_ex (* error_string , 0 );
897
+ * error_string = NULL ;
898
+ }
916
899
917
900
#ifdef SO_BROADCAST
918
- {
919
- int val = 1 ;
920
- if (sockopts & STREAM_SOCKOP_SO_BROADCAST ) {
921
- setsockopt (sock , SOL_SOCKET , SO_BROADCAST , (char * )& val , sizeof (val ));
922
- }
901
+ {
902
+ int val = 1 ;
903
+ if (sockopts & STREAM_SOCKOP_SO_BROADCAST ) {
904
+ setsockopt (sock , SOL_SOCKET , SO_BROADCAST , (char * )& val , sizeof (val ));
923
905
}
906
+ }
924
907
#endif
925
908
926
909
#ifdef TCP_NODELAY
927
- {
928
- int val = 1 ;
929
- if (sockopts & STREAM_SOCKOP_TCP_NODELAY ) {
930
- setsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& val , sizeof (val ));
931
- }
910
+ {
911
+ int val = 1 ;
912
+ if (sockopts & STREAM_SOCKOP_TCP_NODELAY ) {
913
+ setsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& val , sizeof (val ));
932
914
}
915
+ }
933
916
#endif
934
- n = php_network_connect_socket (sock , sa , socklen , asynchronous ,
935
- timeout ? & working_timeout : NULL ,
936
- error_string , error_code );
917
+ n = php_network_connect_socket (sock , sa , socklen , asynchronous ,
918
+ timeout ? & working_timeout : NULL ,
919
+ error_string , error_code );
937
920
938
- if (n != -1 ) {
939
- goto connected ;
940
- }
921
+ if (n != -1 ) {
922
+ goto connected ;
923
+ }
941
924
942
- /* adjust timeout for next attempt */
925
+ /* adjust timeout for next attempt */
943
926
#if HAVE_GETTIMEOFDAY
944
- if (timeout ) {
945
- gettimeofday (& time_now , NULL );
927
+ if (timeout ) {
928
+ gettimeofday (& time_now , NULL );
946
929
947
- if (!timercmp (& time_now , & limit_time , < )) {
948
- /* time limit expired; don't attempt any further connections */
949
- fatal = 1 ;
950
- } else {
951
- /* work out remaining time */
952
- sub_times (limit_time , time_now , & working_timeout );
953
- }
954
- }
955
- #else
956
- if (error_code && * error_code == PHP_TIMEOUT_ERROR_VALUE ) {
957
- /* Don't even bother trying to connect to the next alternative;
958
- * we have no way to determine how long we have already taken
959
- * and it is quite likely that the next attempt will fail too. */
930
+ if (!timercmp (& time_now , & limit_time , < )) {
931
+ /* time limit expired; don't attempt any further connections */
960
932
fatal = 1 ;
961
933
} else {
962
- /* re-use the same initial timeout.
963
- * Not the best thing, but in practice it should be good-enough */
964
- if (timeout ) {
965
- memcpy (& working_timeout , timeout , sizeof (working_timeout ));
966
- }
934
+ /* work out remaining time */
935
+ sub_times (limit_time , time_now , & working_timeout );
936
+ }
937
+ }
938
+ #else
939
+ if (error_code && * error_code == PHP_TIMEOUT_ERROR_VALUE ) {
940
+ /* Don't even bother trying to connect to the next alternative;
941
+ * we have no way to determine how long we have already taken
942
+ * and it is quite likely that the next attempt will fail too. */
943
+ fatal = 1 ;
944
+ } else {
945
+ /* re-use the same initial timeout.
946
+ * Not the best thing, but in practice it should be good-enough */
947
+ if (timeout ) {
948
+ memcpy (& working_timeout , timeout , sizeof (working_timeout ));
967
949
}
968
- #endif
969
950
}
951
+ #endif
970
952
971
953
closesocket (sock );
972
954
}
0 commit comments