def unregister_sock(self, sock): assert isinstance(sock, s.Socket) del self.sockets[sock.fd] with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, 0) rffi.setintfield(ev.c_data, 'c_fd', sock.fd) if epoll_ctl(self.fd, EPOLL_CTL_DEL, sock.fd, ev) < 0: raise rsocket.last_error()
def _ssl_seterror(space, ss, ret): assert ret <= 0 if ss is None: errval = libssl_ERR_peek_last_error() errstr = rffi.charp2str(libssl_ERR_error_string(errval, None)) return ssl_error(space, errstr, errval) elif ss.ssl: err = libssl_SSL_get_error(ss.ssl, ret) else: err = SSL_ERROR_SSL errstr = "" errval = 0 if err == SSL_ERROR_ZERO_RETURN: errstr = "TLS/SSL connection has been closed" errval = PY_SSL_ERROR_ZERO_RETURN elif err == SSL_ERROR_WANT_READ: errstr = "The operation did not complete (read)" errval = PY_SSL_ERROR_WANT_READ elif err == SSL_ERROR_WANT_WRITE: errstr = "The operation did not complete (write)" errval = PY_SSL_ERROR_WANT_WRITE elif err == SSL_ERROR_WANT_X509_LOOKUP: errstr = "The operation did not complete (X509 lookup)" errval = PY_SSL_ERROR_WANT_X509_LOOKUP elif err == SSL_ERROR_WANT_CONNECT: errstr = "The operation did not complete (connect)" errval = PY_SSL_ERROR_WANT_CONNECT elif err == SSL_ERROR_SYSCALL: e = libssl_ERR_get_error() if e == 0: if ret == 0 or space.is_w(ss.w_socket, space.w_None): errstr = "EOF occurred in violation of protocol" errval = PY_SSL_ERROR_EOF elif ret == -1: # the underlying BIO reported an I/0 error error = rsocket.last_error() return interp_socket.converted_error(space, error) else: errstr = "Some I/O error occurred" errval = PY_SSL_ERROR_SYSCALL else: errstr = rffi.charp2str(libssl_ERR_error_string(e, None)) errval = PY_SSL_ERROR_SYSCALL elif err == SSL_ERROR_SSL: e = libssl_ERR_get_error() errval = PY_SSL_ERROR_SSL if e != 0: errstr = rffi.charp2str(libssl_ERR_error_string(e, None)) else: errstr = "A failure in the SSL library occurred" else: errstr = "Invalid error code" errval = PY_SSL_ERROR_INVALID_ERROR_CODE return ssl_error(space, errstr, errval)
def register_sock(self, sock, flags): assert isinstance(sock, s.Socket) assert isinstance(flags, data.UInt) self.sockets[sock.fd] = sock with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, flags.n) rffi.setintfield(ev.c_data, 'c_fd', sock.fd) if epoll_ctl(self.fd, EPOLL_CTL_ADD, sock.fd, ev) < 0: raise rsocket.last_error()
def _ssl_seterror(space, ss, ret): assert ret <= 0 if ss is None: errval = libssl_ERR_peek_last_error() errstr = rffi.charp2str(libssl_ERR_error_string(errval, None)) return ssl_error(space, errstr, errval) elif ss.ssl: err = libssl_SSL_get_error(ss.ssl, ret) else: err = SSL_ERROR_SSL errstr = "" errval = 0 if err == SSL_ERROR_ZERO_RETURN: errstr = "TLS/SSL connection has been closed" errval = PY_SSL_ERROR_ZERO_RETURN elif err == SSL_ERROR_WANT_READ: errstr = "The operation did not complete (read)" errval = PY_SSL_ERROR_WANT_READ elif err == SSL_ERROR_WANT_WRITE: errstr = "The operation did not complete (write)" errval = PY_SSL_ERROR_WANT_WRITE elif err == SSL_ERROR_WANT_X509_LOOKUP: errstr = "The operation did not complete (X509 lookup)" errval = PY_SSL_ERROR_WANT_X509_LOOKUP elif err == SSL_ERROR_WANT_CONNECT: errstr = "The operation did not complete (connect)" errval = PY_SSL_ERROR_WANT_CONNECT elif err == SSL_ERROR_SYSCALL: e = libssl_ERR_get_error() if e == 0: if ret == 0 or space.is_w(ss.w_socket, space.w_None): errstr = "EOF occurred in violation of protocol" errval = PY_SSL_ERROR_EOF elif ret == -1: # the underlying BIO reported an I/0 error error = rsocket.last_error() return interp_socket.converted_error(space, error) else: errstr = "Some I/O error occurred" errval = PY_SSL_ERROR_SYSCALL else: errstr = rffi.charp2str(libssl_ERR_error_string(e, None)) errval = PY_SSL_ERROR_SYSCALL elif err == SSL_ERROR_SSL: e = libssl_ERR_get_error() errval = PY_SSL_ERROR_SSL if e != 0: errstr = rffi.charp2str(libssl_ERR_error_string(e, None)) else: errstr = "A failure in the SSL library occurred" else: errstr = "Invalid error code" errval = PY_SSL_ERROR_INVALID_ERROR_CODE return ssl_error(space, errstr, errval)
def descr_init(self, space, family=-1, type=-1, proto=-1, w_fileno=None): from rpython.rlib.rsocket import _c if space.is_w(w_fileno, space.w_None): if family == -1: family = AF_INET if type == -1: type = SOCK_STREAM if proto == -1: proto = 0 try: if not space.is_w(w_fileno, space.w_None): if _WIN32 and space.isinstance_w(w_fileno, space.w_bytes): # it is possible to pass some bytes representing a socket # in the file descriptor object on winodws fdobj = space.bytes_w(w_fileno) if len(fdobj) != rffi.sizeof(_c.WSAPROTOCOL_INFOW): raise oefmt( space.w_ValueError, "socket descriptor string has wrong size, should be %d bytes", rffi.sizeof(_c.WSAPROTOCOL_INFOW)) info_charptr = rffi.str2charp(fdobj) try: info_ptr = rffi.cast(lltype.Ptr(_c.WSAPROTOCOL_INFOW), info_charptr) type = info_ptr.c_iSocketType fd = _c.WSASocketW(_c.FROM_PROTOCOL_INFO, _c.FROM_PROTOCOL_INFO, _c.FROM_PROTOCOL_INFO, info_ptr, 0, _c.WSA_FLAG_OVERLAPPED) if fd == rsocket.INVALID_SOCKET: raise converted_error(space, rsocket.last_error()) sock = RSocket(info_ptr.c_iAddressFamily, info_ptr.c_iSocketType, info_ptr.c_iProtocol, fd) finally: lltype.free(info_charptr, flavor='raw') else: fd = space.c_filedescriptor_w(w_fileno) if family == -1: family = rsocket.get_socket_family(fd) if type == -1: type = rsocket.getsockopt_int(fd, _c.SOL_SOCKET, _c.SO_TYPE) if proto == -1: proto = get_so_protocol(fd) sock = RSocket(family, type, proto, fd=fd) else: sock = RSocket(family, type, proto, inheritable=False) W_Socket.__init__(self, space, sock) except SocketError as e: raise converted_error(space, e)
def poll(self): timeout = -1 maxevents = FD_SETSIZE - 1 with lltype.scoped_alloc(rffi.CArray(epoll_event), maxevents) as evs: nfds = epoll_wait(self.fd, evs, maxevents, timeout) if nfds < 0: raise rsocket.last_error() output = [None] * nfds for i in xrange(nfds): event = evs[i] sock = self.sockets[event.c_data.c_fd] output[i] = DList([sock, data.UInt(event.c_events)]) return DList(output)
def ioctl_w(self, space, cmd, w_option): from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rwin32 from rpython.rlib.rsocket import _c recv_ptr = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw') try: if cmd == _c.SIO_RCVALL: value_size = rffi.sizeof(rffi.INTP) elif cmd == _c.SIO_KEEPALIVE_VALS: value_size = rffi.sizeof(_c.tcp_keepalive) else: raise oefmt(space.w_ValueError, "invalid ioctl command %d", cmd) value_ptr = lltype.malloc(rffi.VOIDP.TO, value_size, flavor='raw') try: if cmd == _c.SIO_RCVALL: option_ptr = rffi.cast(rffi.INTP, value_ptr) option_ptr[0] = rffi.cast(rffi.INT, space.int_w(w_option)) elif cmd == _c.SIO_KEEPALIVE_VALS: w_onoff, w_time, w_interval = space.unpackiterable( w_option, 3) option_ptr = rffi.cast(lltype.Ptr(_c.tcp_keepalive), value_ptr) option_ptr.c_onoff = rffi.cast(rffi.UINT, space.uint_w(w_onoff)) option_ptr.c_keepalivetime = rffi.cast( rffi.UINT, space.uint_w(w_time)) option_ptr.c_keepaliveinterval = rffi.cast( rffi.UINT, space.uint_w(w_interval)) res = _c.WSAIoctl(self.sock.fd, cmd, value_ptr, value_size, rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL) if res < 0: raise converted_error(space, rsocket.last_error()) finally: if value_ptr: lltype.free(value_ptr, flavor='raw') return space.newint(recv_ptr[0]) finally: lltype.free(recv_ptr, flavor='raw')
def share_w(self, space, processid): from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rwin32 from rpython.rlib.rsocket import _c info_ptr = lltype.malloc(_c.WSAPROTOCOL_INFOW, flavor='raw') try: winprocessid = rffi.cast(rwin32.DWORD, processid) res = _c.WSADuplicateSocketW(self.sock.fd, winprocessid, info_ptr) if res < 0: raise converted_error(space, rsocket.last_error()) bytes_ptr = rffi.cast(rffi.CCHARP, info_ptr) w_bytes = space.newbytes( rffi.charpsize2str(bytes_ptr, rffi.sizeof(_c.WSAPROTOCOL_INFOW))) finally: lltype.free(info_ptr, flavor='raw') return w_bytes
def ioctl_w(self, space, cmd, w_option): from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rwin32 from rpython.rlib.rsocket import _c recv_ptr = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw') try: if cmd == _c.SIO_RCVALL: value_size = rffi.sizeof(rffi.INTP) elif cmd == _c.SIO_KEEPALIVE_VALS: value_size = rffi.sizeof(_c.tcp_keepalive) else: raise oefmt(space.w_ValueError, "invalid ioctl command %d", cmd) value_ptr = lltype.malloc(rffi.VOIDP.TO, value_size, flavor='raw') try: if cmd == _c.SIO_RCVALL: option_ptr = rffi.cast(rffi.INTP, value_ptr) option_ptr[0] = space.int_w(w_option) elif cmd == _c.SIO_KEEPALIVE_VALS: w_onoff, w_time, w_interval = space.unpackiterable(w_option, 3) option_ptr = rffi.cast(lltype.Ptr(_c.tcp_keepalive), value_ptr) option_ptr.c_onoff = space.uint_w(w_onoff) option_ptr.c_keepalivetime = space.uint_w(w_time) option_ptr.c_keepaliveinterval = space.uint_w(w_interval) res = _c.WSAIoctl( self.fd, cmd, value_ptr, value_size, rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL) if res < 0: raise converted_error(space, rsocket.last_error()) finally: if value_ptr: lltype.free(value_ptr, flavor='raw') return space.wrap(recv_ptr[0]) finally: lltype.free(recv_ptr, flavor='raw')
def __init__(self): self.fd = epoll_create1(0) self.sockets = {} if self.fd < 0: raise rsocket.last_error()
def close(space, fd): from rpython.rlib import _rsocket_rffi as _c res = _c.socketclose(fd) if res: converted_error(space, rsocket.last_error())