src/util/socket.h (view raw)
1#ifndef SOCKET_H
2#define SOCKET_H
3
4#include "common.h"
5
6#ifdef _WIN32
7#include <winsock2.h>
8
9typedef SOCKET Socket;
10#else
11#include <fcntl.h>
12#include <netinet/in.h>
13#include <netinet/tcp.h>
14#include <sys/socket.h>
15
16typedef int Socket;
17#endif
18
19
20static inline void SocketSubsystemInitialize() {
21#ifdef _WIN32
22 WSAStartup(MAKEWORD(2, 2), 0);
23#endif
24}
25
26static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) {
27 return write(socket, buffer, size);
28}
29
30static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) {
31 return read(socket, buffer, size);
32}
33
34static inline Socket SocketOpenTCP(int port, uint32_t bindAddress) {
35 Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
36 if (sock < 0) {
37 return sock;
38 }
39
40 struct sockaddr_in bindInfo = {
41 .sin_family = AF_INET,
42 .sin_port = htons(port),
43 .sin_addr = {
44 .s_addr = htonl(bindAddress)
45 }
46 };
47 int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
48 if (err) {
49 close(sock);
50 return -1;
51 }
52 return sock;
53}
54
55static inline Socket SocketConnectTCP(int port, uint32_t destinationAddress) {
56 Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
57 if (sock < 0) {
58 return sock;
59 }
60
61 struct sockaddr_in bindInfo = {
62 .sin_family = AF_INET,
63 .sin_port = htons(port),
64 .sin_addr = {
65 .s_addr = htonl(destinationAddress)
66 }
67 };
68 int err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
69 if (err) {
70 close(sock);
71 return -1;
72 }
73 return sock;
74}
75
76static inline Socket SocketListen(Socket socket, int queueLength) {
77 return listen(socket, queueLength);
78}
79
80static inline Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) {
81 return accept(socket, address, addressLength);
82}
83
84static inline int SocketClose(Socket socket) {
85 return close(socket) >= 0;
86}
87
88static inline int SocketSetBlocking(Socket socket, int blocking) {
89#ifdef _WIN32
90 blocking = !blocking;
91 return ioctlsocket(socket, FIONBIO, &blocking) == NO_ERROR;
92#else
93 int flags = fcntl(socket, F_GETFL);
94 if (flags == -1) {
95 return 0;
96 }
97 if (blocking) {
98 flags &= ~O_NONBLOCK;
99 } else {
100 flags |= O_NONBLOCK;
101 }
102 return fcntl(socket, F_SETFL, flags) >= 0;
103#endif
104}
105
106static inline int SocketSetTCPPush(Socket socket, int push) {
107 return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
108}
109
110#endif