@@ -553,16 +553,65 @@ def fromshare(info):
553
553
return socket (0 , 0 , 0 , info )
554
554
__all__ .append ("fromshare" )
555
555
556
- if hasattr (_socket , "socketpair" ):
556
+ # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
557
+ # This is used if _socket doesn't natively provide socketpair. It's
558
+ # always defined so that it can be patched in for testing purposes.
559
+ def _fallback_socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
560
+ if family == AF_INET :
561
+ host = _LOCALHOST
562
+ elif family == AF_INET6 :
563
+ host = _LOCALHOST_V6
564
+ else :
565
+ raise ValueError ("Only AF_INET and AF_INET6 socket address families "
566
+ "are supported" )
567
+ if type != SOCK_STREAM :
568
+ raise ValueError ("Only SOCK_STREAM socket type is supported" )
569
+ if proto != 0 :
570
+ raise ValueError ("Only protocol zero is supported" )
571
+
572
+ # We create a connected TCP socket. Note the trick with
573
+ # setblocking(False) that prevents us from having to create a thread.
574
+ lsock = socket (family , type , proto )
575
+ try :
576
+ lsock .bind ((host , 0 ))
577
+ lsock .listen ()
578
+ # On IPv6, ignore flow_info and scope_id
579
+ addr , port = lsock .getsockname ()[:2 ]
580
+ csock = socket (family , type , proto )
581
+ try :
582
+ csock .setblocking (False )
583
+ try :
584
+ csock .connect ((addr , port ))
585
+ except (BlockingIOError , InterruptedError ):
586
+ pass
587
+ csock .setblocking (True )
588
+ ssock , _ = lsock .accept ()
589
+ except :
590
+ csock .close ()
591
+ raise
592
+ finally :
593
+ lsock .close ()
557
594
558
- def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
559
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
595
+ # Authenticating avoids using a connection from something else
596
+ # able to connect to {host}:{port} instead of us.
597
+ # We expect only AF_INET and AF_INET6 families.
598
+ try :
599
+ if (
600
+ ssock .getsockname () != csock .getpeername ()
601
+ or csock .getsockname () != ssock .getpeername ()
602
+ ):
603
+ raise ConnectionError ("Unexpected peer connection" )
604
+ except :
605
+ # getsockname() and getpeername() can fail
606
+ # if either socket isn't connected.
607
+ ssock .close ()
608
+ csock .close ()
609
+ raise
560
610
561
- Create a pair of socket objects from the sockets returned by the platform
562
- socketpair() function.
563
- The arguments are the same as for socket() except the default family is
564
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
565
- """
611
+ return (ssock , csock )
612
+
613
+ if hasattr (_socket , "socketpair" ):
614
+ def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
566
615
if family is None :
567
616
try :
568
617
family = AF_UNIX
@@ -574,61 +623,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
574
623
return a , b
575
624
576
625
else :
577
-
578
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
579
- def socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
580
- if family == AF_INET :
581
- host = _LOCALHOST
582
- elif family == AF_INET6 :
583
- host = _LOCALHOST_V6
584
- else :
585
- raise ValueError ("Only AF_INET and AF_INET6 socket address families "
586
- "are supported" )
587
- if type != SOCK_STREAM :
588
- raise ValueError ("Only SOCK_STREAM socket type is supported" )
589
- if proto != 0 :
590
- raise ValueError ("Only protocol zero is supported" )
591
-
592
- # We create a connected TCP socket. Note the trick with
593
- # setblocking(False) that prevents us from having to create a thread.
594
- lsock = socket (family , type , proto )
595
- try :
596
- lsock .bind ((host , 0 ))
597
- lsock .listen ()
598
- # On IPv6, ignore flow_info and scope_id
599
- addr , port = lsock .getsockname ()[:2 ]
600
- csock = socket (family , type , proto )
601
- try :
602
- csock .setblocking (False )
603
- try :
604
- csock .connect ((addr , port ))
605
- except (BlockingIOError , InterruptedError ):
606
- pass
607
- csock .setblocking (True )
608
- ssock , _ = lsock .accept ()
609
- except :
610
- csock .close ()
611
- raise
612
- finally :
613
- lsock .close ()
614
-
615
- # Authenticating avoids using a connection from something else
616
- # able to connect to {host}:{port} instead of us.
617
- # We expect only AF_INET and AF_INET6 families.
618
- try :
619
- if (
620
- ssock .getsockname () != csock .getpeername ()
621
- or csock .getsockname () != ssock .getpeername ()
622
- ):
623
- raise ConnectionError ("Unexpected peer connection" )
624
- except :
625
- # getsockname() and getpeername() can fail
626
- # if either socket isn't connected.
627
- ssock .close ()
628
- csock .close ()
629
- raise
630
-
631
- return (ssock , csock )
626
+ socketpair = _fallback_socketpair
632
627
__all__ .append ("socketpair" )
633
628
634
629
socketpair .__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
0 commit comments