1 #include "net.h"
2 
3 #include <stdio.h>
4 
5 #include "log.h"
6 
7 #ifdef __WINDOWS__
8   typedef int socklen_t;
9 #else
10 # include <sys/types.h>
11 # include <sys/socket.h>
12 # include <netinet/in.h>
13 # include <arpa/inet.h>
14 # include <unistd.h>
15 # define SOCKET_ERROR -1
16   typedef struct sockaddr_in SOCKADDR_IN;
17   typedef struct sockaddr SOCKADDR;
18   typedef struct in_addr IN_ADDR;
19 #endif
20 
21 socket_t
net_connect(uint32_t addr,uint16_t port)22 net_connect(uint32_t addr, uint16_t port) {
23     socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
24     if (sock == INVALID_SOCKET) {
25         perror("socket");
26         return INVALID_SOCKET;
27     }
28 
29     SOCKADDR_IN sin;
30     sin.sin_family = AF_INET;
31     sin.sin_addr.s_addr = htonl(addr);
32     sin.sin_port = htons(port);
33 
34     if (connect(sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
35         perror("connect");
36         net_close(sock);
37         return INVALID_SOCKET;
38     }
39 
40     return sock;
41 }
42 
43 socket_t
net_listen(uint32_t addr,uint16_t port,int backlog)44 net_listen(uint32_t addr, uint16_t port, int backlog) {
45     socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
46     if (sock == INVALID_SOCKET) {
47         perror("socket");
48         return INVALID_SOCKET;
49     }
50 
51     int reuse = 1;
52     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse,
53                    sizeof(reuse)) == -1) {
54         perror("setsockopt(SO_REUSEADDR)");
55     }
56 
57     SOCKADDR_IN sin;
58     sin.sin_family = AF_INET;
59     sin.sin_addr.s_addr = htonl(addr); // htonl() harmless on INADDR_ANY
60     sin.sin_port = htons(port);
61 
62     if (bind(sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
63         perror("bind");
64         net_close(sock);
65         return INVALID_SOCKET;
66     }
67 
68     if (listen(sock, backlog) == SOCKET_ERROR) {
69         perror("listen");
70         net_close(sock);
71         return INVALID_SOCKET;
72     }
73 
74     return sock;
75 }
76 
77 socket_t
net_accept(socket_t server_socket)78 net_accept(socket_t server_socket) {
79     SOCKADDR_IN csin;
80     socklen_t sinsize = sizeof(csin);
81     return accept(server_socket, (SOCKADDR *) &csin, &sinsize);
82 }
83 
84 ssize_t
net_recv(socket_t socket,void * buf,size_t len)85 net_recv(socket_t socket, void *buf, size_t len) {
86     return recv(socket, buf, len, 0);
87 }
88 
89 ssize_t
net_recv_all(socket_t socket,void * buf,size_t len)90 net_recv_all(socket_t socket, void *buf, size_t len) {
91     return recv(socket, buf, len, MSG_WAITALL);
92 }
93 
94 ssize_t
net_send(socket_t socket,const void * buf,size_t len)95 net_send(socket_t socket, const void *buf, size_t len) {
96     return send(socket, buf, len, 0);
97 }
98 
99 ssize_t
net_send_all(socket_t socket,const void * buf,size_t len)100 net_send_all(socket_t socket, const void *buf, size_t len) {
101     ssize_t w = 0;
102     while (len > 0) {
103         w = send(socket, buf, len, 0);
104         if (w == -1) {
105             return -1;
106         }
107         len -= w;
108         buf = (char *) buf + w;
109     }
110     return w;
111 }
112 
113 bool
net_shutdown(socket_t socket,int how)114 net_shutdown(socket_t socket, int how) {
115     return !shutdown(socket, how);
116 }
117