gboolean Socket_Send(SOCKET fd, // IN char *buf, // IN int len) // IN { int left = len; int sent = 0; int rv; int sysErr; while (left > 0) { rv = send(fd, buf + sent, left, 0); if (rv == SOCKET_ERROR) { sysErr = SocketGetLastError(); if (sysErr == SYSERR_EINTR) { continue; } Warning(LGPFX "Send error for socket %d: %d[%s]", fd, sysErr, Err_Errno2String(sysErr)); return FALSE; } left -= rv; sent += rv; } Debug(LGPFX "Sent %d bytes from socket %d\n", len, fd); return TRUE; }
gboolean Socket_Recv(SOCKET fd, // IN char *buf, // OUT int len) // IN { int remaining = len; int rv; int sysErr; while (remaining > 0) { rv = recv(fd, buf , remaining, 0); if (rv == 0) { Warning(LGPFX "Socket %d closed by peer.", fd); return FALSE; } if (rv == SOCKET_ERROR) { sysErr = SocketGetLastError(); if (sysErr == SYSERR_EINTR) { continue; } Warning(LGPFX "Recv error for socket %d: %d[%s]", fd, sysErr, Err_Errno2String(sysErr)); return FALSE; } remaining -= rv; buf += rv; } Debug(LGPFX "Recved %d bytes from socket %d\n", len, fd); return TRUE; }
static gboolean SocketCleanup(void) { #if defined(_WIN32) int err = WSACleanup(); if (err) { Warning(LGPFX "Error in WSACleanup: %d[%s]\n", err, Err_Errno2String(err)); return FALSE; } #endif return TRUE; }
void Socket_Close(SOCKET sock) { int res; #if defined(_WIN32) res = closesocket(sock); #else res = close(sock); #endif if (res == SOCKET_ERROR) { int err = SocketGetLastError(); Warning(LGPFX "Error in closing socket %d: %d[%s]\n", sock, err, Err_Errno2String(err)); } SocketCleanup(); }
static gboolean SocketStartup(void) { #if defined(_WIN32) int err; WSADATA wsaData; err = WSAStartup(MAKEWORD(2, 0), &wsaData); if (err) { Warning(LGPFX "Error in WSAStartup: %d[%s]\n", err, Err_Errno2String(err)); return FALSE; } if (2 != LOBYTE(wsaData.wVersion) || 0 != HIBYTE(wsaData.wVersion)) { Warning(LGPFX "Unsupported Winsock version %d.%d\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); return FALSE; } #endif return TRUE; }
const char * Err_ErrString(void) { return Err_Errno2String(errno); }
SOCKET Socket_ConnectVMCI(unsigned int cid, // IN unsigned int port, // IN gboolean isPriv, // IN SockConnError *outError) // OUT { struct sockaddr_vm addr; SOCKET fd; SockConnError error = SOCKERR_GENERIC; int sysErr; socklen_t addrLen = sizeof addr; int vsockDev = -1; int family = VMCISock_GetAFValueFd(&vsockDev); if (outError) { *outError = SOCKERR_SUCCESS; } if (!SocketStartup()) { goto error; } if (family == -1) { Warning(LGPFX "Couldn't get VMCI socket family info."); goto error; } memset((char *)&addr, 0, sizeof addr); addr.svm_family = family; addr.svm_cid = cid; addr.svm_port = port; Debug(LGPFX "creating new socket, connecting to %u:%u\n", cid, port); fd = socket(addr.svm_family, SOCK_STREAM, 0); if (fd == INVALID_SOCKET) { sysErr = SocketGetLastError(); Warning(LGPFX "failed to create socket, error %d: %s\n", sysErr, Err_Errno2String(sysErr)); goto error; } if (isPriv) { struct sockaddr_vm localAddr; gboolean bindOk = FALSE; int localPort; memset(&localAddr, 0, sizeof localAddr); localAddr.svm_family = addr.svm_family; localAddr.svm_cid = VMCISock_GetLocalCID(); /* Try to bind to port 1~1023 for a privileged user. */ for (localPort = PRIVILEGED_PORT_MAX; localPort >= PRIVILEGED_PORT_MIN; localPort--) { localAddr.svm_port = localPort; if (bind(fd, (struct sockaddr *)&localAddr, sizeof localAddr) != 0) { sysErr = SocketGetLastError(); if (sysErr == SYSERR_EACCESS) { Warning(LGPFX "Couldn't bind to privileged port for " "socket %d\n", fd); error = SOCKERR_EACCESS; Socket_Close(fd); goto error; } if (sysErr == SYSERR_EADDRINUSE) { continue; } Warning(LGPFX "could not bind socket, error %d: %s\n", sysErr, Err_Errno2String(sysErr)); Socket_Close(fd); error = SOCKERR_BIND; goto error; } else { bindOk = TRUE; break; } } if (!bindOk) { Warning(LGPFX "Failed to bind to privileged port for socket %d, " "no port available\n", fd); error = SOCKERR_BIND; Socket_Close(fd); goto error; } else { Debug(LGPFX "Successfully bound to port %d for socket %d\n", localAddr.svm_port, fd); } } if (connect(fd, (struct sockaddr *)&addr, addrLen) != 0) { sysErr = SocketGetLastError(); Warning(LGPFX "socket connect failed, error %d: %s\n", sysErr, Err_Errno2String(sysErr)); Socket_Close(fd); error = SOCKERR_CONNECT; goto error; } VMCISock_ReleaseAFValueFd(vsockDev); Debug(LGPFX "socket %d connected\n", fd); return fd; error: if (outError) { *outError = error; } VMCISock_ReleaseAFValueFd(vsockDev); return INVALID_SOCKET; }
const char * Err_ErrString(void) { return Err_Errno2String(Err_Errno()); }