xpra icon
Bug tracker and wiki

Ticket #983: vsock.patch

File vsock.patch, 8.1 KB (added by Antoine Martin, 4 years ago)

patch attempting to force AF_VSOCK into the python socket class

  • setup.py

     
    127127opengl_ENABLED = DEFAULT and client_ENABLED
    128128html5_ENABLED = DEFAULT and not WIN32 and not OSX
    129129
     130vsock_ENABLED           = sys.platform.startswith("linux")
    130131bencode_ENABLED         = DEFAULT
    131132cython_bencode_ENABLED  = DEFAULT
    132133clipboard_ENABLED       = DEFAULT and not PYTHON3
     
    201202            "dec_avcodec2", "csc_swscale",
    202203            "csc_opencl", "csc_cython", "csc_opencv", "csc_libyuv",
    203204            "memoryview",
    204             "bencode", "cython_bencode",
     205            "bencode", "cython_bencode", "vsock",
    205206            "clipboard",
    206207            "server", "client", "dbus", "x11", "gtk_x11",
    207208            "gtk2", "gtk3", "html5",
     
    23502351                ["xpra/net/bencode/cython_bencode.pyx", buffers_c],
    23512352                **bencode_pkgconfig))
    23522353
     2354if vsock_ENABLED:
     2355    vsock_pkgconfig = pkgconfig()
     2356    cython_add(Extension("xpra.net.vsock",
     2357                ["xpra/net/vsock.pyx"],
     2358                **vsock_pkgconfig))
    23532359
     2360
    23542361if ext_modules:
    23552362    from Cython.Build import cythonize
    23562363    #this causes Cython to fall over itself:
  • xpra/net/vsock_client_test.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6
     7import sys
     8from xpra.net.vsock import client_vconnect, CID_ANY, PORT_ANY       #@UnresolvedImport
     9
     10from xpra.log import Logger
     11log = Logger("network")
     12
     13
     14def main(args):
     15    cid = CID_ANY
     16    port = PORT_ANY
     17    if len(args)>0:
     18        cid = int(args[0])
     19    if len(args)>1:
     20        port = int(args[1])
     21
     22    vsock = client_vconnect(cid=cid, port=port)
     23    log("vsock=%s", vsock)
     24    data = vsock.recv()
     25    log("recv()=%s", data)
     26
     27if __name__ == "__main__":
     28    sys.exit(main(sys.argv[1:]))
  • xpra/net/vsock.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6#cython: boundscheck=False, wraparound=False, cdivision=True
     7
     8import socket as pysocket
     9import struct
     10from xpra.log import Logger
     11log = Logger("network")
     12
     13
     14cdef extern from "string.h":
     15    void *memset(void * ptr, int value, size_t num) nogil
     16
     17cdef extern from "unistd.h":
     18    int close(int fd)
     19
     20cdef extern from "sys/socket.h":
     21    int AF_VSOCK
     22    int SOCK_DGRAM
     23    int SOCK_STREAM
     24    cdef struct sockaddr:
     25        pass
     26    ctypedef int socklen_t
     27    int socket(int socket_family, int socket_type, int protocol)
     28    int bind(int sockfd, const sockaddr *addr, socklen_t addrlen)
     29    int getsockname(int sockfd, sockaddr *addr, socklen_t *addrlen)
     30    int accept(int sockfd, sockaddr *addr, socklen_t *addrlen)
     31    int connect(int sockfd, const sockaddr *addr, socklen_t addrlen)
     32
     33
     34cdef extern from "linux/vm_sockets.h":
     35    unsigned int VMADDR_CID_ANY
     36    unsigned int VMADDR_CID_HYPERVISOR
     37    unsigned int VMADDR_CID_HOST
     38    unsigned int VMADDR_PORT_ANY
     39
     40
     41    unsigned int SO_VM_SOCKETS_BUFFER_SIZE
     42    unsigned int SO_VM_SOCKETS_BUFFER_MIN_SIZE
     43    unsigned int SO_VM_SOCKETS_BUFFER_MAX_SIZE
     44    unsigned int SO_VM_SOCKETS_PEER_HOST_VM_ID
     45    unsigned int SO_VM_SOCKETS_TRUSTED
     46    unsigned int SO_VM_SOCKETS_CONNECT_TIMEOUT
     47    unsigned int SO_VM_SOCKETS_NONBLOCK_TXRX
     48
     49    ctypedef unsigned short __kernel_sa_family_t
     50    cdef struct sockaddr_vm:
     51        __kernel_sa_family_t svm_family
     52        unsigned short svm_reserved1
     53        unsigned int svm_port
     54        unsigned int svm_cid
     55
     56CID_ANY = VMADDR_CID_ANY
     57CID_HYPERVISOR = VMADDR_CID_HYPERVISOR
     58CID_HOST = VMADDR_CID_HOST
     59PORT_ANY = VMADDR_PORT_ANY
     60
     61
     62def server_vsocket(sock_type=SOCK_STREAM, cid=VMADDR_CID_HOST, port=VMADDR_PORT_ANY):
     63    log("server_socket(%s)", (cid, port, sock_type))
     64    assert sock_type in (SOCK_STREAM, SOCK_DGRAM), "invalid socket type %s" % sock_type
     65    assert cid in (VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR, VMADDR_CID_HOST), "invalid cid %s" % cid
     66    assert port==VMADDR_PORT_ANY or (port>0 and port<65536)
     67    log("socket(%i, %i, 0)", AF_VSOCK, sock_type)
     68    cdef int sockfd = socket(AF_VSOCK, sock_type, 0)
     69    log("socket(AF_VSOCK, SOCK_DGRAM, 0)=%i", sockfd)
     70    if sockfd<0:
     71        raise Exception("AF_VSOCK not supported")
     72   
     73    cdef sockaddr_vm vmsock
     74    memset(&vmsock, 0, sizeof(sockaddr_vm))
     75    vmsock.svm_family = AF_VSOCK
     76    vmsock.svm_cid = cid
     77    vmsock.svm_port = port
     78
     79    if bind(sockfd, <sockaddr*> &vmsock, sizeof(sockaddr_vm)):
     80        close(sockfd)
     81        raise Exception("failed to bind to AF_VSOCK socket")
     82
     83    cdef socklen_t socklen = sizeof(sockaddr_vm)
     84    if getsockname(sockfd, <sockaddr *> &vmsock, &socklen):
     85        close(sockfd)
     86        raise Exception("getsockname failed")
     87    log("cid=%i, port=%i", vmsock.svm_cid, vmsock.svm_port)
     88    vsock = VSocket(sockfd)
     89    return vsock
     90
     91class VSocket(object):
     92    def __init__(self, sockfd):
     93        self.sockfd = sockfd
     94        self.sock = pysocket.fromfd(sockfd, AF_VSOCK, 0)
     95    def __getattr__(self, attr):
     96        return getattr(self.sock, attr)
     97    def accept(self):
     98        cdef sockaddr_vm vmsock
     99        cdef socklen_t socklen = sizeof(sockaddr_vm)
     100        memset(&vmsock, 0, socklen)
     101        cdef int fd = accept(self.sockfd, <sockaddr*> &vmsock, &socklen)
     102        if fd<0:
     103            raise Exception("accept failed: %s" % fd)
     104        conn = pysocket.fromfd(fd, AF_VSOCK, 0)
     105        if getsockname(fd, <sockaddr *> &vmsock, &socklen):
     106            close(fd)
     107            raise Exception("getsockname failed")
     108        address = "hello"
     109        return conn, address
     110
     111
     112def vsock_client_host_stream(port=0):
     113    pass
     114
     115
     116def client_vconnect(sock_type=SOCK_STREAM, cid=VMADDR_CID_ANY, port=VMADDR_PORT_ANY):
     117    log("client_vconnect(%s)", (cid, port, sock_type))
     118    assert sock_type in (SOCK_STREAM, SOCK_DGRAM), "invalid socket type %s" % sock_type
     119    assert cid in (VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR, VMADDR_CID_HOST), "invalid cid %s" % cid
     120    assert port==VMADDR_PORT_ANY or (port>0 and port<65536)
     121    log("socket(%i, %i, 0)", AF_VSOCK, sock_type)
     122    cdef int sockfd = socket(AF_VSOCK, sock_type, 0)
     123    log("socket(AF_VSOCK, SOCK_DGRAM, 0)=%i", sockfd)
     124    if sockfd<0:
     125        raise Exception("AF_VSOCK not supported")
     126   
     127    cdef sockaddr_vm vmsock
     128    memset(&vmsock, 0, sizeof(sockaddr_vm))
     129    vmsock.svm_family = AF_VSOCK
     130    vmsock.svm_cid = cid
     131    vmsock.svm_port = port
     132
     133    if connect(sockfd, <sockaddr *> &vmsock, sizeof(sockaddr_vm)):
     134        raise Exception("failed to connect to server vsock %i:%i", cid, port)
     135
     136    vsock = VSocket(sockfd)
     137    return vsock
  • xpra/net/vsock_server_test.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6
     7import sys
     8from xpra.net.vsock import server_vsocket
     9
     10from xpra.log import Logger
     11log = Logger("network")
     12
     13
     14def main():
     15    sock = server_vsocket()
     16    log("sock=%s", sock)
     17    #import time
     18    #time.sleep(10)
     19    sock.listen(1)
     20    log("listening")
     21    while True:
     22        connection, client_address = sock.accept()
     23        log("new connection! %s", (connection, client_address))
     24        data = connection.recv(1024)
     25        log("got data: %s" % data)
     26        connection.send("hello")
     27    return 0
     28
     29if __name__ == "__main__":
     30    sys.exit(main())