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