diff -ru ../Twisted-11.0.0/twisted/internet/abstract.py ./twisted/internet/abstract.py
|
old
|
new
|
|
| 9 | 9 | Maintainer: Itamar Shtull-Trauring |
| 10 | 10 | """ |
| 11 | 11 | |
| | 12 | import socket |
| | 13 | |
| 12 | 14 | from zope.interface import implements |
| 13 | 15 | |
| 14 | 16 | # Twisted Imports |
| … |
… |
|
| 412 | 414 | return -1 |
| 413 | 415 | |
| 414 | 416 | |
| 415 | | def isIPAddress(addr): |
| | 417 | def isIPv6Address(addr): |
| | 418 | """ |
| | 419 | Determine whether the given string represents an IPv6 address. |
| | 420 | |
| | 421 | @param addr: A string which may or may not be the hexadecimal |
| | 422 | representation of an IPv6 address. |
| | 423 | |
| | 424 | @rtype: C{bool} |
| | 425 | @return: C{True} if C{addr} represents an IPv6 address, C{False} |
| | 426 | otherwise. |
| | 427 | """ |
| | 428 | if addr.find(":") != 1: |
| | 429 | try: |
| | 430 | socket.getaddrinfo(addr, 0, socket.AF_INET6, 0, 0, socket.AI_NUMERICHOST) |
| | 431 | except socket.gaierror: |
| | 432 | pass |
| | 433 | else: |
| | 434 | return True |
| | 435 | return False |
| | 436 | |
| | 437 | def isIPv4Address(addr): |
| 416 | 438 | """ |
| 417 | 439 | Determine whether the given string represents an IPv4 address. |
| 418 | 440 | |
| … |
… |
|
| 437 | 459 | return True |
| 438 | 460 | return False |
| 439 | 461 | |
| | 462 | def isIPAddress(addr): |
| | 463 | """ |
| | 464 | Determine whether the given string represents an IPv4 or IPv6 address. |
| | 465 | |
| | 466 | @type addr: C{str} |
| | 467 | @param addr: A string which may or may not be the decimal dotted |
| | 468 | representation of an IPv4 address. |
| | 469 | |
| | 470 | @rtype: C{bool} |
| | 471 | @return: C{True} if C{addr} represents an IPv4 address, C{False} |
| | 472 | """ |
| | 473 | return isIPv4Address(addr) or isIPv6Address(addr) |
| 440 | 474 | |
| 441 | 475 | __all__ = ["FileDescriptor"] |
diff -ru ../Twisted-11.0.0/twisted/internet/address.py ./twisted/internet/address.py
|
old
|
new
|
|
| 5 | 5 | Address objects for network connections. |
| 6 | 6 | """ |
| 7 | 7 | |
| 8 | | import warnings, os |
| | 8 | import warnings, os, socket |
| 9 | 9 | |
| 10 | 10 | from zope.interface import implements |
| 11 | 11 | |
| … |
… |
|
| 13 | 13 | from twisted.python import util |
| 14 | 14 | |
| 15 | 15 | |
| 16 | | class IPv4Address(object, util.FancyEqMixin): |
| | 16 | class IPAddress(object, util.FancyEqMixin): |
| 17 | 17 | """ |
| 18 | | Object representing an IPv4 socket endpoint. |
| | 18 | Object representing an IP socket endpoint. |
| 19 | 19 | |
| 20 | 20 | @ivar type: A string describing the type of transport, either 'TCP' or |
| 21 | 21 | 'UDP'. |
| … |
… |
|
| 25 | 25 | |
| 26 | 26 | implements(IAddress) |
| 27 | 27 | |
| 28 | | compareAttributes = ('type', 'host', 'port') |
| | 28 | compareAttributes = ('type', 'family', 'host', 'port') |
| 29 | 29 | |
| 30 | | def __init__(self, type, host, port, _bwHack = None): |
| | 30 | def __init__(self, type, family, host, port, _bwHack = None): |
| 31 | 31 | assert type in ('TCP', 'UDP') |
| 32 | 32 | self.type = type |
| | 33 | self.family = family |
| 33 | 34 | self.host = host |
| 34 | 35 | self.port = port |
| 35 | 36 | if _bwHack is not None: |
| … |
… |
|
| 37 | 38 | DeprecationWarning, stacklevel=2) |
| 38 | 39 | |
| 39 | 40 | def __repr__(self): |
| 40 | | return 'IPv4Address(%s, %r, %d)' % (self.type, self.host, self.port) |
| | 41 | family_str = "IPv4" if self.family == socket.AF_INET else "IPv6" |
| | 42 | return 'IPAddress(%s, %s, %r, %d)' % (self.type, family_str, self.host, self.port) |
| 41 | 43 | |
| 42 | 44 | |
| 43 | 45 | def __hash__(self): |
| 44 | | return hash((self.type, self.host, self.port)) |
| 45 | | |
| | 46 | return hash((self.type, self.family, self.host, self.port)) |
| 46 | 47 | |
| | 48 | class IPv4Address(IPAddress): |
| | 49 | """ |
| | 50 | Generic version of IPv4Address. |
| | 51 | """ |
| | 52 | def __init(self, type, host, port): |
| | 53 | IPAddress.__init__(type, socket.AF_INET, host, port, None) |
| 47 | 54 | |
| 48 | 55 | class UNIXAddress(object, util.FancyEqMixin): |
| 49 | 56 | """ |
| … |
… |
|
| 92 | 99 | |
| 93 | 100 | |
| 94 | 101 | |
| | 102 | class _ServerFactoryIPAddress(IPAddress): |
| | 103 | def __eq__(self, other): |
| | 104 | if isinstance(other, IPAddress): |
| | 105 | a = (self.type, self.family, self.host, self.port) |
| | 106 | b = (other.type, other.family, other.host, other.port) |
| | 107 | return a == b |
| | 108 | return False |
| | 109 | |
| 95 | 110 | # These are for buildFactory backwards compatability due to |
| 96 | 111 | # stupidity-induced inconsistency. |
| 97 | 112 | |
diff -ru ../Twisted-11.0.0/twisted/internet/base.py ./twisted/internet/base.py
|
old
|
new
|
|
| 249 | 249 | else: |
| 250 | 250 | userDeferred.callback(result) |
| 251 | 251 | |
| | 252 | def _lookup(self, name): |
| | 253 | """ |
| | 254 | Replacement for gethostbyname. |
| | 255 | """ |
| | 256 | ai = socket.getaddrinfo(name, 0) |
| | 257 | assert len(ai) > 0 and len(ai[0]) >= 5 |
| | 258 | |
| | 259 | # Sort the result. IPv4 addresses should be preferred over |
| | 260 | # IPv6 addresses to keep legacy applications working. |
| | 261 | ai = sorted(ai, key=lambda fields: fields[0]) |
| | 262 | |
| | 263 | return ai[0][4][0] |
| 252 | 264 | |
| 253 | 265 | def getHostByName(self, name, timeout = (1, 3, 11, 45)): |
| 254 | 266 | """ |
| … |
… |
|
| 265 | 277 | userDeferred = defer.Deferred() |
| 266 | 278 | lookupDeferred = threads.deferToThreadPool( |
| 267 | 279 | self.reactor, self.reactor.getThreadPool(), |
| 268 | | socket.gethostbyname, name) |
| | 280 | self._lookup, name) |
| 269 | 281 | cancelCall = self.reactor.callLater( |
| 270 | 282 | timeoutDelay, self._cleanup, name, lookupDeferred) |
| 271 | 283 | self._runningQueries[lookupDeferred] = (userDeferred, cancelCall) |
diff -ru ../Twisted-11.0.0/twisted/internet/endpoints.py ./twisted/internet/endpoints.py
|
old
|
new
|
|
| 145 | 145 | |
| 146 | 146 | |
| 147 | 147 | |
| 148 | | class TCP4ServerEndpoint(object): |
| | 148 | class TCPServerEndpoint(object): |
| 149 | 149 | """ |
| 150 | | TCP server endpoint with an IPv4 configuration |
| | 150 | TCP server endpoint with an IP configuration |
| 151 | 151 | |
| 152 | 152 | @ivar _reactor: An L{IReactorTCP} provider. |
| 153 | 153 | |
| … |
… |
|
| 186 | 186 | backlog=self._backlog, |
| 187 | 187 | interface=self._interface) |
| 188 | 188 | |
| | 189 | """ Legacy: TCP4ServerEndpoint """ |
| | 190 | class TCP4ServerEndpoint(TCPServerEndpoint): |
| | 191 | pass |
| 189 | 192 | |
| 190 | | |
| 191 | | class TCP4ClientEndpoint(object): |
| | 193 | class TCPClientEndpoint(object): |
| 192 | 194 | """ |
| 193 | | TCP client endpoint with an IPv4 configuration. |
| | 195 | TCP client endpoint with an IP configuration. |
| 194 | 196 | |
| 195 | 197 | @ivar _reactor: An L{IReactorTCP} provider. |
| 196 | 198 | |
| … |
… |
|
| 245 | 247 | except: |
| 246 | 248 | return defer.fail() |
| 247 | 249 | |
| | 250 | """ Legacy: TCP4ClientEndpoint """ |
| | 251 | class TCP4ClientEndpoint(TCPClientEndpoint): |
| | 252 | pass |
| 248 | 253 | |
| 249 | | |
| 250 | | class SSL4ServerEndpoint(object): |
| | 254 | class SSLServerEndpoint(object): |
| 251 | 255 | """ |
| 252 | | SSL secured TCP server endpoint with an IPv4 configuration. |
| | 256 | SSL secured TCP server endpoint with an IP configuration. |
| 253 | 257 | |
| 254 | 258 | @ivar _reactor: An L{IReactorSSL} provider. |
| 255 | 259 | |
| … |
… |
|
| 301 | 305 | backlog=self._backlog, |
| 302 | 306 | interface=self._interface) |
| 303 | 307 | |
| | 308 | """ Legacy: SSL4ServerEndpoint """ |
| | 309 | class SSL4ServerEndpoint(SSLServerEndpoint): |
| | 310 | pass |
| 304 | 311 | |
| 305 | | |
| 306 | | class SSL4ClientEndpoint(object): |
| | 312 | class SSLClientEndpoint(object): |
| 307 | 313 | """ |
| 308 | | SSL secured TCP client endpoint with an IPv4 configuration |
| | 314 | SSL secured TCP client endpoint with an IP configuration |
| 309 | 315 | |
| 310 | 316 | @ivar _reactor: An L{IReactorSSL} provider. |
| 311 | 317 | |
| … |
… |
|
| 369 | 375 | except: |
| 370 | 376 | return defer.fail() |
| 371 | 377 | |
| 372 | | |
| | 378 | """ Legacy: SSL4ClientEndpoint """ |
| | 379 | class SSL4ClientEndpoint(SSLClientEndpoint): |
| | 380 | pass |
| 373 | 381 | |
| 374 | 382 | class UNIXServerEndpoint(object): |
| 375 | 383 | """ |
| … |
… |
|
| 652 | 660 | |
| 653 | 661 | # Mappings from description "names" to endpoint constructors. |
| 654 | 662 | _endpointServerFactories = { |
| 655 | | 'TCP': TCP4ServerEndpoint, |
| 656 | | 'SSL': SSL4ServerEndpoint, |
| | 663 | 'TCP': TCPServerEndpoint, |
| | 664 | 'SSL': SSLServerEndpoint, |
| 657 | 665 | 'UNIX': UNIXServerEndpoint, |
| 658 | 666 | } |
| 659 | 667 | |
| 660 | 668 | _endpointClientFactories = { |
| 661 | | 'TCP': TCP4ClientEndpoint, |
| 662 | | 'SSL': SSL4ClientEndpoint, |
| | 669 | 'TCP': TCPClientEndpoint, |
| | 670 | 'SSL': SSLClientEndpoint, |
| 663 | 671 | 'UNIX': UNIXClientEndpoint, |
| 664 | 672 | } |
| 665 | 673 | |
diff -ru ../Twisted-11.0.0/twisted/internet/iocpreactor/tcp.py ./twisted/internet/iocpreactor/tcp.py
|
old
|
new
|
|
| 261 | 261 | def __init__(self, host, port, bindAddress, connector, reactor): |
| 262 | 262 | self.connector = connector |
| 263 | 263 | self.addr = (host, port) |
| | 264 | self.addressFamily = connector.family |
| 264 | 265 | self.reactor = reactor |
| 265 | 266 | # ConnectEx documentation says socket _has_ to be bound |
| 266 | 267 | if bindAddress is None: |
| … |
… |
|
| 352 | 353 | |
| 353 | 354 | def getHost(self): |
| 354 | 355 | """ |
| 355 | | Returns an IPv4Address. |
| | 356 | Returns an IPAddress. |
| 356 | 357 | |
| 357 | 358 | This indicates the address from which I am connecting. |
| 358 | 359 | """ |
| 359 | | return address.IPv4Address('TCP', *self.socket.getsockname()) |
| | 360 | return address.IPAddress('TCP', self.socket.family, *self.socket.getsockname()) |
| 360 | 361 | |
| 361 | 362 | |
| 362 | 363 | def getPeer(self): |
| 363 | 364 | """ |
| 364 | | Returns an IPv4Address. |
| | 365 | Returns an IPAddress. |
| 365 | 366 | |
| 366 | 367 | This indicates the address that I am connected to. |
| 367 | 368 | """ |
| 368 | | return address.IPv4Address('TCP', *self.realAddress) |
| | 369 | return address.IPv4Address('TCP', self.addressFamily, *self.realAddress) |
| 369 | 370 | |
| 370 | 371 | |
| 371 | 372 | def __repr__(self): |
| … |
… |
|
| 423 | 424 | |
| 424 | 425 | def getHost(self): |
| 425 | 426 | """ |
| 426 | | Returns an IPv4Address. |
| | 427 | Returns an IPAddress. |
| 427 | 428 | |
| 428 | 429 | This indicates the server's address. |
| 429 | 430 | """ |
| … |
… |
|
| 432 | 433 | |
| 433 | 434 | def getPeer(self): |
| 434 | 435 | """ |
| 435 | | Returns an IPv4Address. |
| | 436 | Returns an IPAddress. |
| 436 | 437 | |
| 437 | 438 | This indicates the client's address. |
| 438 | 439 | """ |
| … |
… |
|
| 482 | 483 | |
| 483 | 484 | |
| 484 | 485 | def startListening(self): |
| | 486 | # Get the correct address family by using getaddrinfo() on the interface address |
| | 487 | ai = socket.getaddrinfo(self.interface, self.port) |
| | 488 | self.addressFamily = ai[0][0] |
| | 489 | |
| 485 | 490 | try: |
| 486 | 491 | skt = self.reactor.createSocket(self.addressFamily, |
| 487 | 492 | self.socketType) |
| … |
… |
|
| 574 | 579 | |
| 575 | 580 | def getHost(self): |
| 576 | 581 | """ |
| 577 | | Returns an IPv4Address. |
| | 582 | Returns an IPAddress. |
| 578 | 583 | |
| 579 | 584 | This indicates the server's address. |
| 580 | 585 | """ |
| 581 | | return address.IPv4Address('TCP', *self.socket.getsockname()) |
| | 586 | return address.IPAddress('TCP', self.socket.family, *self.socket.getsockname()) |
| 582 | 587 | |
| 583 | 588 | |
| 584 | 589 | def cbAccept(self, rc, bytes, evt): |
| … |
… |
|
| 605 | 610 | assert family == self.addressFamily |
| 606 | 611 | |
| 607 | 612 | protocol = self.factory.buildProtocol( |
| 608 | | address._ServerFactoryIPv4Address('TCP', rAddr[0], rAddr[1])) |
| | 613 | address._ServerFactoryIPAddress('TCP', family, rAddr[0], rAddr[1])) |
| 609 | 614 | if protocol is None: |
| 610 | 615 | evt.newskt.close() |
| 611 | 616 | else: |
| 612 | 617 | s = self.sessionno |
| 613 | 618 | self.sessionno = s+1 |
| 614 | 619 | transport = Server(evt.newskt, protocol, |
| 615 | | address.IPv4Address('TCP', rAddr[0], rAddr[1]), |
| 616 | | address.IPv4Address('TCP', lAddr[0], lAddr[1]), |
| | 620 | address.IPAddress('TCP', family, rAddr[0], rAddr[1]), |
| | 621 | address.IPAddress('TCP', family, lAddr[0], lAddr[1]), |
| 617 | 622 | s, self.reactor) |
| 618 | 623 | protocol.makeConnection(transport) |
| 619 | 624 | return True |
diff -ru ../Twisted-11.0.0/twisted/internet/iocpreactor/udp.py ./twisted/internet/iocpreactor/udp.py
|
old
|
new
|
|
| 51 | 51 | |
| 52 | 52 | abstract.FileHandle.__init__(self, reactor) |
| 53 | 53 | |
| | 54 | # Get the correct address family by using getaddrinfo() on the interface address |
| | 55 | ai = socket.getaddrinfo(self.interface, self.port) |
| | 56 | self.addressFamily = ai[0][0] |
| | 57 | |
| 54 | 58 | skt = socket.socket(self.addressFamily, self.socketType) |
| 55 | 59 | addrLen = _iocp.maxAddrLen(skt.fileno()) |
| 56 | 60 | self.addressBuffer = _iocp.AllocateReadBuffer(addrLen) |
| … |
… |
|
| 269 | 273 | |
| 270 | 274 | def getHost(self): |
| 271 | 275 | """ |
| 272 | | Returns an IPv4Address. |
| | 276 | Returns an IPAddress. |
| 273 | 277 | |
| 274 | 278 | This indicates the address from which I am connecting. |
| 275 | 279 | """ |
| 276 | | return address.IPv4Address('UDP', *self.socket.getsockname()) |
| | 280 | return address.IPAddress('UDP', self.socket.family, *self.socket.getsockname()) |
| 277 | 281 | |
| 278 | 282 | |
| 279 | 283 | |
diff -ru ../Twisted-11.0.0/twisted/internet/tcp.py ./twisted/internet/tcp.py
|
old
|
new
|
|
| 695 | 695 | # BaseClient.__init__ is invoked later |
| 696 | 696 | self.connector = connector |
| 697 | 697 | self.addr = (host, port) |
| 698 | | |
| | 698 | self.addressFamily = connector.family |
| | 699 | |
| 699 | 700 | whenDone = self.resolveAddress |
| 700 | 701 | err = None |
| 701 | 702 | skt = None |
| … |
… |
|
| 714 | 715 | self._finishInit(whenDone, skt, err, reactor) |
| 715 | 716 | |
| 716 | 717 | def getHost(self): |
| 717 | | """Returns an IPv4Address. |
| | 718 | """Returns an IPAddress. |
| 718 | 719 | |
| 719 | 720 | This indicates the address from which I am connecting. |
| 720 | 721 | """ |
| 721 | | return address.IPv4Address('TCP', *self.socket.getsockname()) |
| | 722 | return address.IPAddress('TCP', self.socket.family, *self.socket.getsockname()) |
| 722 | 723 | |
| 723 | 724 | def getPeer(self): |
| 724 | | """Returns an IPv4Address. |
| | 725 | """Returns an IPAddress. |
| 725 | 726 | |
| 726 | 727 | This indicates the address that I am connected to. |
| 727 | 728 | """ |
| 728 | | return address.IPv4Address('TCP', *self.realAddress) |
| | 729 | return address.IPAddress('TCP', self.addressFamily, *self.realAddress) |
| 729 | 730 | |
| 730 | 731 | def __repr__(self): |
| 731 | 732 | s = '<%s to %s at %x>' % (self.__class__, self.addr, unsignedID(self)) |
| … |
… |
|
| 776 | 777 | |
| 777 | 778 | |
| 778 | 779 | def getHost(self): |
| 779 | | """Returns an IPv4Address. |
| | 780 | """Returns an IPAddress. |
| 780 | 781 | |
| 781 | 782 | This indicates the server's address. |
| 782 | 783 | """ |
| 783 | | return address.IPv4Address('TCP', *self.socket.getsockname()) |
| | 784 | return address.IPAddress('TCP', self.socket.family, *self.socket.getsockname()) |
| 784 | 785 | |
| 785 | 786 | def getPeer(self): |
| 786 | | """Returns an IPv4Address. |
| | 787 | """Returns an IPAddress. |
| 787 | 788 | |
| 788 | 789 | This indicates the client's address. |
| 789 | 790 | """ |
| 790 | | return address.IPv4Address('TCP', *self.client) |
| | 791 | return address.IPAddress('TCP', self.socket.family, *self.client) |
| 791 | 792 | |
| 792 | 793 | |
| 793 | 794 | |
| … |
… |
|
| 848 | 849 | return "<%s of %s (not listening)>" % (self.__class__, self.factory.__class__) |
| 849 | 850 | |
| 850 | 851 | def createInternetSocket(self): |
| | 852 | # Get the correct address family by using getaddrinfo() on the interface address |
| | 853 | ai = socket.getaddrinfo(self.interface, self.port) |
| | 854 | self.addressFamily = ai[0][0] |
| 851 | 855 | s = base.BasePort.createInternetSocket(self) |
| 852 | 856 | if platformType == "posix" and sys.platform != "cygwin": |
| 853 | 857 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
| … |
… |
|
| 863 | 867 | try: |
| 864 | 868 | skt = self.createInternetSocket() |
| 865 | 869 | skt.bind((self.interface, self.port)) |
| | 870 | pass |
| 866 | 871 | except socket.error, le: |
| 867 | 872 | raise CannotListenError, (self.interface, self.port, le) |
| 868 | 873 | |
| … |
… |
|
| 885 | 890 | |
| 886 | 891 | |
| 887 | 892 | def _buildAddr(self, (host, port)): |
| 888 | | return address._ServerFactoryIPv4Address('TCP', host, port) |
| | 893 | return address._ServerFactoryIPAddress('TCP', self.addressFamily, host, port) |
| 889 | 894 | |
| 890 | 895 | |
| 891 | 896 | def doRead(self): |
| … |
… |
|
| 939 | 944 | raise |
| 940 | 945 | |
| 941 | 946 | fdesc._setCloseOnExec(skt.fileno()) |
| | 947 | |
| | 948 | # IPv6 addresses have usually more than two fields, reduce them. |
| | 949 | if len(addr) > 2: |
| | 950 | addr = addr[0:2] |
| | 951 | |
| 942 | 952 | protocol = self.factory.buildProtocol(self._buildAddr(addr)) |
| 943 | 953 | if protocol is None: |
| 944 | 954 | skt.close() |
| … |
… |
|
| 1009 | 1019 | return reflect.qual(self.factory.__class__) |
| 1010 | 1020 | |
| 1011 | 1021 | def getHost(self): |
| 1012 | | """Returns an IPv4Address. |
| | 1022 | """Returns an IPAddress. |
| 1013 | 1023 | |
| 1014 | 1024 | This indicates the server's address. |
| 1015 | 1025 | """ |
| 1016 | | return address.IPv4Address('TCP', *self.socket.getsockname()) |
| | 1026 | return address.IPAddress('TCP', self.socket.family, *self.socket.getsockname()) |
| 1017 | 1027 | |
| 1018 | 1028 | class Connector(base.BaseConnector): |
| 1019 | 1029 | def __init__(self, host, port, factory, timeout, bindAddress, reactor=None): |
| | 1030 | ai = socket.getaddrinfo(host, port) |
| | 1031 | self.family = ai[0][0] |
| 1020 | 1032 | self.host = host |
| 1021 | 1033 | if isinstance(port, types.StringTypes): |
| 1022 | 1034 | try: |
| … |
… |
|
| 1031 | 1043 | return Client(self.host, self.port, self.bindAddress, self, self.reactor) |
| 1032 | 1044 | |
| 1033 | 1045 | def getDestination(self): |
| 1034 | | return address.IPv4Address('TCP', self.host, self.port) |
| | 1046 | return address.IPAddress('TCP', self.family, self.host, self.port) |
diff -ru ../Twisted-11.0.0/twisted/internet/udp.py ./twisted/internet/udp.py
|
old
|
new
|
|
| 86 | 86 | self._connectToProtocol() |
| 87 | 87 | |
| 88 | 88 | def _bindSocket(self): |
| | 89 | # Get the correct address family by using getaddrinfo() on the interface address |
| | 90 | ai = socket.getaddrinfo(self.interface, self.port) |
| | 91 | self.addressFamily = ai[0][0] |
| | 92 | |
| 89 | 93 | try: |
| 90 | 94 | skt = self.createInternetSocket() |
| 91 | 95 | skt.bind((self.interface, self.port)) |
| … |
… |
|
| 238 | 242 | |
| 239 | 243 | def getHost(self): |
| 240 | 244 | """ |
| 241 | | Returns an IPv4Address. |
| | 245 | Returns an IPAddress. |
| 242 | 246 | |
| 243 | 247 | This indicates the address from which I am connecting. |
| 244 | 248 | """ |
| 245 | | return address.IPv4Address('UDP', *self.socket.getsockname()) |
| | 249 | return address.IPAddress('UDP', self.socket.family, *self.socket.getsockname()) |
| 246 | 250 | |
| 247 | 251 | |
| 248 | 252 | |