예제 #1
0
 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()
예제 #2
0
파일: interp_ssl.py 프로젝트: charred/pypy
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)
예제 #3
0
 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()
예제 #4
0
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)
예제 #5
0
 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)
예제 #6
0
    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)
예제 #7
0
    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')
예제 #8
0
    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
예제 #9
0
    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')
예제 #10
0
 def __init__(self):
     self.fd = epoll_create1(0)
     self.sockets = {}
     if self.fd < 0:
         raise rsocket.last_error()
예제 #11
0
def close(space, fd):
    from rpython.rlib import _rsocket_rffi as _c
    res = _c.socketclose(fd)
    if res:
        converted_error(space, rsocket.last_error())