Introduction
Introduction Statistics Contact Development Disclaimer Help
sock.c - quark - quark web server
git clone git://git.suckless.org/quark
Log
Files
Refs
LICENSE
---
sock.c (4386B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <arpa/inet.h>
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <netdb.h>
6 #include <netinet/in.h>
7 #include <stddef.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <sys/stat.h>
13 #include <sys/time.h>
14 #include <sys/un.h>
15 #include <unistd.h>
16
17 #include "sock.h"
18 #include "util.h"
19
20 int
21 sock_get_ips(const char *host, const char* port)
22 {
23 struct addrinfo hints = {
24 .ai_flags = AI_NUMERICSERV,
25 .ai_family = AF_UNSPEC,
26 .ai_socktype = SOCK_STREAM,
27 };
28 struct addrinfo *ai, *p;
29 int ret, insock = 0;
30
31 if ((ret = getaddrinfo(host, port, &hints, &ai))) {
32 die("getaddrinfo: %s", gai_strerror(ret));
33 }
34
35 for (p = ai; p; p = p->ai_next) {
36 if ((insock = socket(p->ai_family, p->ai_socktype,
37 p->ai_protocol)) < 0) {
38 continue;
39 }
40 if (setsockopt(insock, SOL_SOCKET, SO_REUSEADDR,
41 &(int){1}, sizeof(int)) < 0) {
42 die("setsockopt:");
43 }
44 if (bind(insock, p->ai_addr, p->ai_addrlen) < 0) {
45 /* bind failed, close the insock and retry */
46 if (close(insock) < 0) {
47 die("close:");
48 }
49 continue;
50 }
51 break;
52 }
53 freeaddrinfo(ai);
54 if (!p) {
55 /* we exhaustet the addrinfo-list and found no connectio…
56 if (errno == EACCES) {
57 die("You need to run as root or have "
58 "CAP_NET_BIND_SERVICE set to bind to "
59 "privileged ports");
60 } else {
61 die("bind:");
62 }
63 }
64
65 if (listen(insock, SOMAXCONN) < 0) {
66 die("listen:");
67 }
68
69 return insock;
70 }
71
72 int
73 sock_get_uds(const char *udsname, uid_t uid, gid_t gid)
74 {
75 struct sockaddr_un addr = {
76 .sun_family = AF_UNIX,
77 };
78 size_t udsnamelen;
79 int insock, sockmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
80 S_IROTH | S_IWOTH;
81
82 if ((insock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
83 die("socket:");
84 }
85
86 if ((udsnamelen = strlen(udsname)) > sizeof(addr.sun_path) - 1) {
87 die("UNIX-domain socket name truncated");
88 }
89 memcpy(addr.sun_path, udsname, udsnamelen + 1);
90
91 if (bind(insock, (const struct sockaddr *)&addr, sizeof(addr)) <…
92 die("bind '%s':", udsname);
93 }
94
95 if (listen(insock, SOMAXCONN) < 0) {
96 sock_rem_uds(udsname);
97 die("listen:");
98 }
99
100 if (chmod(udsname, sockmode) < 0) {
101 sock_rem_uds(udsname);
102 die("chmod '%s':", udsname);
103 }
104
105 if (chown(udsname, uid, gid) < 0) {
106 sock_rem_uds(udsname);
107 die("chown '%s':", udsname);
108 }
109
110 return insock;
111 }
112
113 void
114 sock_rem_uds(const char *udsname)
115 {
116 if (unlink(udsname) < 0) {
117 die("unlink '%s':", udsname);
118 }
119 }
120
121 int
122 sock_set_timeout(int fd, int sec)
123 {
124 struct timeval tv;
125
126 tv.tv_sec = sec;
127 tv.tv_usec = 0;
128
129 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0…
130 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0…
131 warn("setsockopt:");
132 return 1;
133 }
134
135 return 0;
136 }
137
138 int
139 sock_set_nonblocking(int fd)
140 {
141 int flags;
142
143 if ((flags = fcntl(fd, F_GETFL, 0)) < 0) {
144 warn("fcntl:");
145 return 1;
146 }
147
148 flags |= O_NONBLOCK;
149
150 if (fcntl(fd, F_SETFL, flags) < 0) {
151 warn("fcntl:");
152 return 1;
153 }
154
155 return 0;
156 }
157
158 int
159 sock_get_inaddr_str(const struct sockaddr_storage *in_sa, char *str,
160 size_t len)
161 {
162 switch (in_sa->ss_family) {
163 case AF_INET:
164 if (!inet_ntop(AF_INET,
165 &(((struct sockaddr_in *)in_sa)->sin_addr…
166 str, len)) {
167 warn("inet_ntop:");
168 return 1;
169 }
170 break;
171 case AF_INET6:
172 if (!inet_ntop(AF_INET6,
173 &(((struct sockaddr_in6 *)in_sa)->sin6_ad…
174 str, len)) {
175 warn("inet_ntop:");
176 return 1;
177 }
178 break;
179 case AF_UNIX:
180 snprintf(str, len, "uds");
181 break;
182 default:
183 snprintf(str, len, "-");
184 }
185
186 return 0;
187 }
188
189 int
190 sock_same_addr(const struct sockaddr_storage *sa1, const struct sockaddr…
191 {
192 /* return early if address-families don't match */
193 if (sa1->ss_family != sa2->ss_family) {
194 return 0;
195 }
196
197 switch (sa1->ss_family) {
198 case AF_INET6:
199 return memcmp(((struct sockaddr_in6 *)sa1)->sin6_addr.s6…
200 ((struct sockaddr_in6 *)sa2)->sin6_addr.s6…
201 sizeof(((struct sockaddr_in6 *)sa1)->sin6_…
202 case AF_INET:
203 return ((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
204 ((struct sockaddr_in *)sa2)->sin_addr.s_addr;
205 default: /* AF_UNIX */
206 return strcmp(((struct sockaddr_un *)sa1)->sun_path,
207 ((struct sockaddr_un *)sa2)->sun_path) == …
208 }
209 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.