blob: dec91aaf0a53fa949cda5a0771c1ecc1b2275155 [file] [log] [blame]
Willy Tarreau92fb9832007-10-16 17:34:28 +02001/*
2 * UNIX SOCK_STREAM protocol layer (uxst)
3 *
Willy Tarreaueb472682010-05-28 18:46:57 +02004 * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
Willy Tarreau92fb9832007-10-16 17:34:28 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <ctype.h>
14#include <errno.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <syslog.h>
20#include <time.h>
21
Willy Tarreau92fb9832007-10-16 17:34:28 +020022#include <sys/socket.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <sys/un.h>
26
27#include <common/compat.h>
28#include <common/config.h>
29#include <common/debug.h>
Willy Tarreaud740bab2007-10-28 11:14:07 +010030#include <common/errors.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020031#include <common/mini-clist.h>
32#include <common/standard.h>
33#include <common/time.h>
34#include <common/version.h>
35
Willy Tarreau92fb9832007-10-16 17:34:28 +020036#include <types/global.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020037
Willy Tarreau92fb9832007-10-16 17:34:28 +020038#include <proto/fd.h>
39#include <proto/log.h>
40#include <proto/protocols.h>
41#include <proto/proto_uxst.h>
Willy Tarreauc63190d2012-05-11 14:23:52 +020042#include <proto/sock_raw.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020043#include <proto/task.h>
44
Emeric Bruncf20bf12010-10-22 16:06:11 +020045static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
46static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
Willy Tarreaudabf2e22007-10-28 21:59:24 +010047static int uxst_unbind_listeners(struct protocol *proto);
48
49/* Note: must not be declared <const> as its list will be overwritten */
50static struct protocol proto_unix = {
51 .name = "unix_stream",
52 .sock_domain = PF_UNIX,
53 .sock_type = SOCK_STREAM,
54 .sock_prot = 0,
55 .sock_family = AF_UNIX,
56 .sock_addrlen = sizeof(struct sockaddr_un),
57 .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),/* path len */
Willy Tarreaubbebbbf2012-05-07 21:22:09 +020058 .accept = &listener_accept,
Emeric Bruncf20bf12010-10-22 16:06:11 +020059 .bind = uxst_bind_listener,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010060 .bind_all = uxst_bind_listeners,
61 .unbind_all = uxst_unbind_listeners,
62 .enable_all = enable_all_listeners,
63 .disable_all = disable_all_listeners,
Willy Tarreau59b94792012-05-11 16:16:40 +020064 .get_src = uxst_get_src,
65 .get_dst = uxst_get_dst,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010066 .listeners = LIST_HEAD_INIT(proto_unix.listeners),
67 .nb_listeners = 0,
68};
69
Willy Tarreaudabf2e22007-10-28 21:59:24 +010070/********************************
71 * 1) low-level socket functions
72 ********************************/
73
Willy Tarreau59b94792012-05-11 16:16:40 +020074/*
75 * Retrieves the source address for the socket <fd>, with <dir> indicating
76 * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
77 * success, -1 in case of error. The socket's source address is stored in
78 * <sa> for <salen> bytes.
79 */
80int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
81{
82 if (dir)
83 return getsockname(fd, sa, &salen);
84 else
85 return getpeername(fd, sa, &salen);
86}
87
88
89/*
90 * Retrieves the original destination address for the socket <fd>, with <dir>
91 * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
92 * case of success, -1 in case of error. The socket's source address is stored
93 * in <sa> for <salen> bytes.
94 */
95int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
96{
97 if (dir)
98 return getpeername(fd, sa, &salen);
99 else
100 return getsockname(fd, sa, &salen);
101}
102
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100103
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100104/* Tries to destroy the UNIX stream socket <path>. The socket must not be used
105 * anymore. It practises best effort, and no error is returned.
106 */
107static void destroy_uxst_socket(const char *path)
108{
109 struct sockaddr_un addr;
110 int sock, ret;
111
112 /* We might have been chrooted, so we may not be able to access the
113 * socket. In order to avoid bothering the other end, we connect with a
114 * wrong protocol, namely SOCK_DGRAM. The return code from connect()
115 * is enough to know if the socket is still live or not. If it's live
116 * in mode SOCK_STREAM, we get EPROTOTYPE or anything else but not
117 * ECONNREFUSED. In this case, we do not touch it because it's used
118 * by some other process.
119 */
120 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
121 if (sock < 0)
122 return;
123
124 addr.sun_family = AF_UNIX;
125 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
126 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
127 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
128 if (ret < 0 && errno == ECONNREFUSED) {
129 /* Connect failed: the socket still exists but is not used
130 * anymore. Let's remove this socket now.
131 */
132 unlink(path);
133 }
134 close(sock);
135}
136
137
138/********************************
139 * 2) listener-oriented functions
140 ********************************/
141
142
143/* This function creates a UNIX socket associated to the listener. It changes
144 * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
145 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
Willy Tarreau92fb9832007-10-16 17:34:28 +0200146 */
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100147static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200148{
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100149 int fd;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200150 char tempname[MAXPATHLEN];
151 char backname[MAXPATHLEN];
152 struct sockaddr_un addr;
Willy Tarreaub40dc942010-11-07 12:10:51 +0100153 const char *msg = NULL;
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100154 const char *path;
155
156 int ret;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200157
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100158 /* ensure we never return garbage */
159 if (errmsg && errlen)
160 *errmsg = 0;
161
162 if (listener->state != LI_ASSIGNED)
163 return ERR_NONE; /* already bound */
164
165 path = ((struct sockaddr_un *)&listener->addr)->sun_path;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200166
167 /* 1. create socket names */
168 if (!path[0]) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100169 msg = "Invalid empty name for a UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200170 goto err_return;
171 }
172
173 ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
174 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100175 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200176 goto err_return;
177 }
178
179 ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
180 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100181 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200182 goto err_return;
183 }
184
185 /* 2. clean existing orphaned entries */
186 if (unlink(tempname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100187 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200188 goto err_return;
189 }
190
191 if (unlink(backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100192 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200193 goto err_return;
194 }
195
196 /* 3. backup existing socket */
197 if (link(path, backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100198 msg = "error when trying to preserve previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200199 goto err_return;
200 }
201
202 /* 4. prepare new socket */
203 addr.sun_family = AF_UNIX;
204 strncpy(addr.sun_path, tempname, sizeof(addr.sun_path));
205 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
206
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100207 fd = socket(PF_UNIX, SOCK_STREAM, 0);
208 if (fd < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100209 msg = "cannot create UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200210 goto err_unlink_back;
211 }
212
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100213 if (fd >= global.maxsock) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100214 msg = "socket(): not enough free sockets, raise -n argument";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200215 goto err_unlink_temp;
216 }
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100217
218 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100219 msg = "cannot make UNIX socket non-blocking";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200220 goto err_unlink_temp;
221 }
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100222
223 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
Willy Tarreau92fb9832007-10-16 17:34:28 +0200224 /* note that bind() creates the socket <tempname> on the file system */
Willy Tarreaub40dc942010-11-07 12:10:51 +0100225 msg = "cannot bind UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200226 goto err_unlink_temp;
227 }
228
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100229 /* <uid> and <gid> different of -1 will be used to change the socket owner.
230 * If <mode> is not 0, it will be used to restrict access to the socket.
231 * While it is known not to be portable on every OS, it's still useful
232 * where it works.
233 */
234 if (((listener->perm.ux.uid != -1 || listener->perm.ux.gid != -1) &&
235 (chown(tempname, listener->perm.ux.uid, listener->perm.ux.gid) == -1)) ||
236 (listener->perm.ux.mode != 0 && chmod(tempname, listener->perm.ux.mode) == -1)) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100237 msg = "cannot change UNIX socket ownership";
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200238 goto err_unlink_temp;
239 }
240
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100241 if (listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100242 msg = "cannot listen to UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200243 goto err_unlink_temp;
244 }
245
246 /* 5. install.
247 * Point of no return: we are ready, we'll switch the sockets. We don't
248 * fear loosing the socket <path> because we have a copy of it in
249 * backname.
250 */
251 if (rename(tempname, path) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100252 msg = "cannot switch final and temporary UNIX sockets";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200253 goto err_rename;
254 }
255
256 /* 6. cleanup */
257 unlink(backname); /* no need to keep this one either */
258
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100259 /* the socket is now listening */
260 listener->fd = fd;
261 listener->state = LI_LISTEN;
262
263 /* the function for the accept() event */
264 fd_insert(fd);
Willy Tarreaueb472682010-05-28 18:46:57 +0200265 fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100266 fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
Willy Tarreaueabf3132008-08-29 23:36:51 +0200267 fdtab[fd].owner = listener; /* reference the listener instead of a task */
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100268 fdtab[fd].state = FD_STLISTEN;
Willy Tarreau8d5d77e2009-10-18 07:25:52 +0200269 fdinfo[fd].peeraddr = NULL;
270 fdinfo[fd].peerlen = 0;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100271 return ERR_NONE;
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100272 err_rename:
273 ret = rename(backname, path);
274 if (ret < 0 && errno == ENOENT)
275 unlink(path);
276 err_unlink_temp:
277 unlink(tempname);
278 close(fd);
279 err_unlink_back:
280 unlink(backname);
281 err_return:
282 if (msg && errlen)
283 snprintf(errmsg, errlen, "%s [%s]", msg, path);
284 return ERR_FATAL | ERR_ALERT;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100285}
286
287/* This function closes the UNIX sockets for the specified listener.
288 * The listener enters the LI_ASSIGNED state. It always returns ERR_NONE.
289 */
290static int uxst_unbind_listener(struct listener *listener)
291{
Willy Tarreaube58c382011-07-24 18:28:10 +0200292 if (listener->state > LI_ASSIGNED) {
293 unbind_listener(listener);
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100294 destroy_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path);
295 }
296 return ERR_NONE;
297}
298
299/* Add a listener to the list of unix stream listeners. The listener's state
300 * is automatically updated from LI_INIT to LI_ASSIGNED. The number of
301 * listeners is updated. This is the function to use to add a new listener.
302 */
303void uxst_add_listener(struct listener *listener)
304{
305 if (listener->state != LI_INIT)
306 return;
307 listener->state = LI_ASSIGNED;
308 listener->proto = &proto_unix;
309 LIST_ADDQ(&proto_unix.listeners, &listener->proto_list);
310 proto_unix.nb_listeners++;
311}
312
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100313/********************************
314 * 3) protocol-oriented functions
315 ********************************/
316
317
Willy Tarreau92fb9832007-10-16 17:34:28 +0200318/* This function creates all UNIX sockets bound to the protocol entry <proto>.
319 * It is intended to be used as the protocol's bind_all() function.
320 * The sockets will be registered but not added to any fd_set, in order not to
321 * loose them across the fork(). A call to uxst_enable_listeners() is needed
322 * to complete initialization.
323 *
324 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
325 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200326static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200327{
328 struct listener *listener;
329 int err = ERR_NONE;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200330
331 list_for_each_entry(listener, &proto->listeners, proto_list) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200332 err |= uxst_bind_listener(listener, errmsg, errlen);
333 if (err & ERR_ABORT)
334 break;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200335 }
Willy Tarreau92fb9832007-10-16 17:34:28 +0200336 return err;
337}
338
Willy Tarreau92fb9832007-10-16 17:34:28 +0200339
340/* This function stops all listening UNIX sockets bound to the protocol
341 * <proto>. It does not detaches them from the protocol.
342 * It always returns ERR_NONE.
343 */
344static int uxst_unbind_listeners(struct protocol *proto)
345{
346 struct listener *listener;
347
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100348 list_for_each_entry(listener, &proto->listeners, proto_list)
349 uxst_unbind_listener(listener);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200350 return ERR_NONE;
351}
352
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100353
354/********************************
355 * 4) high-level functions
356 ********************************/
357
Willy Tarreau92fb9832007-10-16 17:34:28 +0200358__attribute__((constructor))
359static void __uxst_protocol_init(void)
360{
361 protocol_register(&proto_unix);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200362}
363
364
365/*
366 * Local variables:
367 * c-indent-level: 8
368 * c-basic-offset: 8
369 * End:
370 */