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