#include "oslib.h" #define SOCKET_TCP 0 #define SOCKET_SSL 1 // SSL section SSL_CTX* sslContext; int lolib_enableSsl(const char* certfilePath, const char* keyfilePath, char* keyfilePassword) { SSL_library_init(); const SSL_METHOD *method = TLS_server_method(); sslContext = SSL_CTX_new(method); if (sslContext == NULL) return 1; if (SSL_CTX_use_certificate_file(sslContext, certfilePath, SSL_FILETYPE_PEM) <= 0) return 2; SSL_CTX_set_default_passwd_cb_userdata(sslContext, keyfilePassword); if (SSL_CTX_use_PrivateKey_file(sslContext, keyfilePath, SSL_FILETYPE_PEM) <= 0) return 3; if (!SSL_CTX_check_private_key(sslContext)) return 4; return 0; } int lolib_acceptSslSocket(LemonServerSocket serverSocket, struct LemonClientSocket *dst) { SOCKET connFd = accept(serverSocket, 0, 0); if (connFd == -1) return 1; SSL* newSSL = SSL_new(sslContext); SSL_set_fd(newSSL, connFd); if (SSL_accept(newSSL) != 1) { SSL_shutdown(newSSL); SSL_free(newSSL); return 2; } dst->type = SOCKET_SSL; dst->descriptor.sslDescriptor = newSSL; return 0; } // OS Abstraction section int lolib_init() { #ifdef _WIN32 WSADATA wsa_data; return WSAStartup(MAKEWORD(1,1), &wsa_data); #else return 0; #endif } int lolib_finalize(struct LemonClientSocket *socket) { int status; switch (socket->type) { case SOCKET_TCP: #ifdef _WIN32 status = shutdown(socket->descriptor.tcpDescriptor, SD_BOTH); if (status == 0) { status = closesocket(socket->descriptor.tcpDescriptor); } #else status = shutdown(socket->descriptor.tcpDescriptor, SHUT_RDWR); if (status == 0) { status = close(socket->descriptor.tcpDescriptor); } #endif break; case SOCKET_SSL: SSL_shutdown(socket->descriptor.sslDescriptor); SSL_free(socket->descriptor.sslDescriptor); } return status; } int lolib_quit() { if (sslContext != NULL) SSL_CTX_free(sslContext); #ifdef _WIN32 return WSACleanup(); #else return 0; #endif } // Wrapper section int lolib_createServerSocket(const char* bindAddress, unsigned short port, LemonServerSocket *dst) { struct sockaddr_in serverAddr; SOCKET serverFd; if ((serverFd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return 1; serverAddr.sin_family = AF_INET; inet_pton(AF_INET, bindAddress, &serverAddr.sin_addr); serverAddr.sin_port = htons(port); if (bind(serverFd, (const struct sockaddr *) &serverAddr, sizeof(serverAddr)) != 0) return 2; if (listen(serverFd, 5) != 0) return 3; *dst = serverFd; return 0; } int lolib_acceptTcpSocket(LemonServerSocket serverSocket, struct LemonClientSocket *dst) { SOCKET connFd = accept(serverSocket, 0, 0); if (connFd == -1) return 1; dst->type = SOCKET_TCP; dst->descriptor.tcpDescriptor = connFd; return 0; } int lolib_writeSocket(struct LemonClientSocket *socket, const char* data, unsigned int dataLength) { switch (socket->type) { case SOCKET_TCP: return send(socket->descriptor.tcpDescriptor, data, dataLength, 0); default: return -2; } } int lolib_readSocket(struct LemonClientSocket *socket, char *data, unsigned int bytesToRead) { switch (socket->type) { case SOCKET_TCP: return recv(socket->descriptor.tcpDescriptor, data, bytesToRead, 0); default: return -2; } }