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 = {
52 .s_addr = htonl(bindAddress)
53 }
54 };
55 int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
56 if (err) {
57 close(sock);
58 return -1;
59 }
60 return sock;
61}
62
63static inline Socket SocketConnectTCP(int port, uint32_t destinationAddress) {
64 Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
65 if (SOCKET_FAILED(sock)) {
66 return sock;
67 }
68
69 struct sockaddr_in bindInfo = {
70 .sin_family = AF_INET,
71 .sin_port = htons(port),
72 .sin_addr = {
73 .s_addr = htonl(destinationAddress)
74 }
75 };
76 int err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
77 if (err) {
78 close(sock);
79 return -1;
80 }
81 return sock;
82}
83
84static inline Socket SocketListen(Socket socket, int queueLength) {
85 return listen(socket, queueLength);
86}
87
88static inline Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) {
89 return accept(socket, address, addressLength);
90}
91
92static inline int SocketClose(Socket socket) {
93 return close(socket) >= 0;
94}
95
96static inline int SocketSetBlocking(Socket socket, int blocking) {
97#ifdef _WIN32
98 u_long unblocking = !blocking;
99 return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR;
100#else
101 int flags = fcntl(socket, F_GETFL);
102 if (flags == -1) {
103 return 0;
104 }
105 if (blocking) {
106 flags &= ~O_NONBLOCK;
107 } else {
108 flags |= O_NONBLOCK;
109 }
110 return fcntl(socket, F_SETFL, flags) >= 0;
111#endif
112}
113
114static inline int SocketSetTCPPush(Socket socket, int push) {
115 return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
116}
117
118#endif