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