diff --git a/client/Makefile b/client/Makefile index 160e1766..6a51b1d8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -10,4 +10,4 @@ LDFLAGS+=`pkg-config --libs libssl openssl` CFLAGS+=`pkg-config --cflags spice-protocol` all: - gcc ${CFLAGS} -o main main.c spice/spice.c ${LDFLAGS} + gcc ${CFLAGS} -o main main.c spice/spice.c ivshmem/ivshmem.c ${LDFLAGS} diff --git a/client/debug.h b/client/debug.h index 7d0a3bf4..e57fa2b7 100644 --- a/client/debug.h +++ b/client/debug.h @@ -1,3 +1,5 @@ +#include + #ifdef DEBUG #define DEBUG_PRINT(type, fmt, args...) do {fprintf(stderr, type " %-30s : %-5u | " fmt "\n", __FUNCTION__, __LINE__, ##args);} while (0) #else @@ -9,7 +11,7 @@ #define DEBUG_ERROR(fmt, args...) DEBUG_PRINT("[E]", fmt, ##args) #define DEBUG_FIXME(fmt, args...) DEBUG_PRINT("[F]", fmt, ##args) -#ifdef DEBUG_SPICE +#if defined(DEBUG_SPICE) | defined(DEBUG_IVSHMEM) #define DEBUG_PROTO(fmt, args...) DEBUG_PRINT("[P]", fmt, ##args) #else #define DEBUG_PROTO(fmt, args...) do {} while(0) diff --git a/client/ivshmem/ivshmem.c b/client/ivshmem/ivshmem.c new file mode 100644 index 00000000..426cd1fa --- /dev/null +++ b/client/ivshmem/ivshmem.c @@ -0,0 +1,145 @@ +#include "ivshmem.h" + +#define DEBUG +#define DEBUG_IVSHMEM +#include "debug.h" + +#include +#include +#include +#include + +#include +#include + +struct IVSHMEM +{ + bool connected; + int socket; +}; + +struct IVSHMEM ivshmem = +{ + .connected = false, + .socket = -1 +}; + +// ============================================================================ +// internal functions + +void ivshmem_cleanup(); +bool ivshmem_read(void * buffer, const ssize_t size); + +// ============================================================================ + +bool ivshmem_connect(const char * unix_socket) +{ + ivshmem.socket = socket(AF_UNIX, SOCK_STREAM, 0); + if (ivshmem.socket < 0) + { + DEBUG_ERROR("socket creation failed"); + return false; + } + + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, unix_socket, sizeof(addr.sun_path)); + + if (connect(ivshmem.socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) + { + DEBUG_ERROR("socket connect failed"); + ivshmem_cleanup(); + return false; + } + + ivshmem.connected = true; + + struct IVSHMEMInit init; + if (!ivshmem_read(&init.version, sizeof(init.version))) + { + DEBUG_ERROR("read protocol version failed"); + ivshmem_cleanup(); + return false; + } + + if (init.version != 0) + { + DEBUG_ERROR("unsupported protocol version %ld", init.version); + ivshmem_cleanup(); + return false; + } + + if (!ivshmem_read(&init.clientID, sizeof(init.clientID))) + { + DEBUG_ERROR("read client id failed"); + ivshmem_cleanup(); + return false; + } + + if (!ivshmem_read(&init.unused, sizeof(init.unused))) + { + DEBUG_ERROR("read unused failed"); + ivshmem_cleanup(); + return false; + } + + if (!ivshmem_read(&init.sharedFD, sizeof(init.sharedFD))) + { + DEBUG_ERROR("read shared memory file descriptor failed"); + ivshmem_cleanup(); + return false; + } + + DEBUG_PROTO("Protocol : %ld", init.version ); + DEBUG_PROTO("Client ID: %ld", init.clientID); + DEBUG_PROTO("Unused : %ld", init.unused ); + DEBUG_PROTO("Shared FD: %ld", init.sharedFD); + + return true; +} + +// ============================================================================ + +void ivshmem_cleanup() +{ + if (ivshmem.socket >= 0) + { + close(ivshmem.socket); + ivshmem.socket = -1; + } + + ivshmem.connected = false; +} + +// ============================================================================ + +void ivshmem_close() +{ + if (!ivshmem.connected) + { + DEBUG_WARN("socket not connected"); + return; + } + + ivshmem_cleanup(); +} + +// ============================================================================ + +bool ivshmem_read(void * buffer, const ssize_t size) +{ + if (!ivshmem.connected) + { + DEBUG_ERROR("not connected"); + return false; + } + + ssize_t len = read(ivshmem.socket, buffer, size); + if (len != size) + { + DEBUG_ERROR("incomplete read"); + return false; + } + + return true; +} \ No newline at end of file diff --git a/client/ivshmem/ivshmem.h b/client/ivshmem/ivshmem.h new file mode 100644 index 00000000..5710e0c8 --- /dev/null +++ b/client/ivshmem/ivshmem.h @@ -0,0 +1,13 @@ +#include +#include + +struct IVSHMEMInit +{ + int64_t version; + int64_t clientID; + int64_t unused; + int64_t sharedFD; +}; + +bool ivshmem_connect(const char * unix_socket); +void ivshmem_close(); \ No newline at end of file