def write(self, datagram, addr=None): """ Write a datagram. @param addr: should be a tuple (ip, port), can be None in connected mode. """ if self._connectedAddr: assert addr in (None, self._connectedAddr) try: return self.socket.send(datagram) except OSError as se: no = se.args[0] if no == errno.WSAEINTR: return self.write(datagram) elif no == errno.WSAEMSGSIZE: raise error.MessageLengthError("message too long") elif no in ( errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE, ): self.protocol.connectionRefused() else: raise else: assert addr != None if (not isIPAddress(addr[0]) and not isIPv6Address(addr[0]) and addr[0] != "<broadcast>"): raise error.InvalidAddressError( addr[0], "write() only accepts IP addresses, not hostnames") if isIPAddress(addr[0]) and self.addressFamily == socket.AF_INET6: raise error.InvalidAddressError( addr[0], "IPv6 port write() called with IPv4 address") if isIPv6Address(addr[0]) and self.addressFamily == socket.AF_INET: raise error.InvalidAddressError( addr[0], "IPv4 port write() called with IPv6 address") try: return self.socket.sendto(datagram, addr) except OSError as se: no = se.args[0] if no == errno.WSAEINTR: return self.write(datagram, addr) elif no == errno.WSAEMSGSIZE: raise error.MessageLengthError("message too long") elif no in ( errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE, ): # in non-connected UDP ECONNREFUSED is platform dependent, # I think and the info is not necessarily useful. # Nevertheless maybe we should call connectionRefused? XXX return else: raise
def write(self, datagram, addr=None): """ Write a datagram. @type datagram: C{str} @param datagram: The datagram to be sent. @type addr: C{tuple} containing C{str} as first element and C{int} as second element, or L{None} @param addr: A tuple of (I{stringified IPv4 or IPv6 address}, I{integer port number}); can be L{None} in connected mode. """ if self._connectedAddr: assert addr in (None, self._connectedAddr) try: return self.socket.send(datagram) except socket.error as se: no = se.args[0] if no == EINTR: return self.write(datagram) elif no == EMSGSIZE: raise error.MessageLengthError("message too long") elif no == ECONNREFUSED: self.protocol.connectionRefused() else: raise else: assert addr != None if (not abstract.isIPAddress(addr[0]) and not abstract.isIPv6Address(addr[0]) and addr[0] != "<broadcast>"): raise error.InvalidAddressError( addr[0], "write() only accepts IP addresses, not hostnames") if ((abstract.isIPAddress(addr[0]) or addr[0] == "<broadcast>") and self.addressFamily == socket.AF_INET6): raise error.InvalidAddressError( addr[0], "IPv6 port write() called with IPv4 or broadcast address") if (abstract.isIPv6Address(addr[0]) and self.addressFamily == socket.AF_INET): raise error.InvalidAddressError( addr[0], "IPv4 port write() called with IPv6 address") try: return self.socket.sendto(datagram, addr) except socket.error as se: no = se.args[0] if no == EINTR: return self.write(datagram, addr) elif no == EMSGSIZE: raise error.MessageLengthError("message too long") elif no == ECONNREFUSED: # in non-connected UDP ECONNREFUSED is platform dependent, I # think and the info is not necessarily useful. Nevertheless # maybe we should call connectionRefused? XXX return else: raise
def _setAddressFamily(self): """ Resolve address family for the socket. """ if abstract.isIPv6Address(self.interface): self.addressFamily = socket.AF_INET6 elif abstract.isIPAddress(self.interface): self.addressFamily = socket.AF_INET elif self.interface: raise error.InvalidAddressError(self.interface, 'not an IPv4 or IPv6 address.')
def connect(self, host, port): """ 'Connect' to remote server. """ if self._connectedAddr: raise RuntimeError("already connected, reconnecting is not currently supported") if not abstract.isIPAddress(host) and not abstract.isIPv6Address(host): raise error.InvalidAddressError( host, 'not an IPv4 or IPv6 address.') self._connectedAddr = (host, port) self.socket.connect((host, port))
def connect(self, host, port): """ 'Connect' to remote server. """ if self._connectedAddr: raise RuntimeError( "already connected, reconnecting is not currently supported " "(talk to itamar if you want this)") if not isIPAddress(host) and not isIPv6Address(host): raise error.InvalidAddressError(host, "not an IPv4 or IPv6 address.") self._connectedAddr = (host, port) self.socket.connect((host, port))
no = se.args[0] if no == errno.WSAEINTR: return self.write(datagram) elif no == errno.WSAEMSGSIZE: raise error.MessageLengthError("message too long") elif no in (errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE): self.protocol.connectionRefused() else: raise else: assert addr != None if (not isIPAddress(addr[0]) and not isIPv6Address(addr[0]) and addr[0] != "<broadcast>"): raise error.InvalidAddressError( addr[0], "write() only accepts IP addresses, not hostnames") if isIPAddress(addr[0]) and self.addressFamily == socket.AF_INET6: raise error.InvalidAddressError( addr[0], "IPv6 port write() called with IPv4 address") if isIPv6Address(addr[0]) and self.addressFamily == socket.AF_INET: raise error.InvalidAddressError( addr[0], "IPv4 port write() called with IPv6 address") try: return self.socket.sendto(datagram, addr) except socket.error, se: no = se.args[0] if no == errno.WSAEINTR: return self.write(datagram, addr) elif no == errno.WSAEMSGSIZE: raise error.MessageLengthError("message too long")