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