-
Notifications
You must be signed in to change notification settings - Fork 76
/
Copy pathsockutils.c
138 lines (117 loc) · 2.69 KB
/
sockutils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright (c) 2021-2024 Siddharth Chandrasekaran <sidcha.dev@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <utils/sockutils.h>
int sock_unix_listen(const char *path, int max_clients)
{
int rc, fd;
socklen_t len;
struct sockaddr_un sock_serv;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return -1;
sock_serv.sun_family = AF_UNIX;
strcpy(sock_serv.sun_path, path);
len = sizeof(sock_serv.sun_family) + strlen(path) + 1;
unlink(path);
rc = bind(fd, (const struct sockaddr *)&sock_serv, len);
if (rc < 0)
return -1;
rc = listen(fd, max_clients);
if (rc < 0)
return -1;
return fd;
}
int sock_unix_connect(const char *path)
{
int rc, fd;
socklen_t len;
struct sockaddr_un serv_addr;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return -1;
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, path);
len = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path) + 1;
rc = connect(fd, (struct sockaddr *)&serv_addr, len);
if (rc != 0)
return -1;
return fd;
}
int sock_stream_connect(const char *host, int port)
{
int fd;
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(port)
};
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed!");
return -1;
}
if (inet_pton(AF_INET, host, &addr.sin_addr) <= 0) {
perror("Invalid address / Address not supported!");
return -1;
}
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect failed");
return -1;
}
return fd;
}
int sock_stream_listen(int port, int nr_clients)
{
int fd, opt = 1;
struct sockaddr_in address = {
.sin_family = AF_INET,
.sin_addr = {
.s_addr = INADDR_ANY,
},
.sin_port = htons(port),
};
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
return -1;
}
if (setsockopt(fd, SOL_SOCKET,
SO_REUSEADDR /*| SO_REUSEPORT*/, &opt, sizeof(opt))) {
perror("setsockopt failed");
return -1;
}
if (bind(fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("bind failed");
return -1;
}
if (listen(fd, nr_clients) < 0) {
perror("listen failed");
return -1;
}
return fd;
}
int sock_wait(int listening_socket_fd)
{
int client_fd;
struct sockaddr_in addr;
size_t addr_len = sizeof(addr);
client_fd = accept(listening_socket_fd, (struct sockaddr *)&addr,
(socklen_t *)&addr_len);
if (client_fd < 0) {
perror("accept failed");
return -1;
}
return client_fd;
}
int sock_shutdown(int listening_socket_fd)
{
return shutdown(listening_socket_fd, SHUT_RDWR);
}