blob: 511753395f6b179608c032c2a46a7cc7a32f23f0 [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
22#include <sys/param.h>
23#include <sys/socket.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <sys/un.h>
27
28#include <common/compat.h>
29#include <common/config.h>
30#include <common/debug.h>
Willy Tarreaud740bab2007-10-28 11:14:07 +010031#include <common/errors.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020032#include <common/mini-clist.h>
33#include <common/standard.h>
34#include <common/time.h>
35#include <common/version.h>
36
Willy Tarreau92fb9832007-10-16 17:34:28 +020037#include <types/global.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020038
Willy Tarreau92fb9832007-10-16 17:34:28 +020039#include <proto/fd.h>
40#include <proto/log.h>
41#include <proto/protocols.h>
42#include <proto/proto_uxst.h>
Willy Tarreau92fb9832007-10-16 17:34:28 +020043#include <proto/stream_sock.h>
44#include <proto/task.h>
45
46#ifndef MAXPATHLEN
47#define MAXPATHLEN 128
48#endif
49
Emeric Bruncf20bf12010-10-22 16:06:11 +020050static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
51static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
Willy Tarreaudabf2e22007-10-28 21:59:24 +010052static int uxst_unbind_listeners(struct protocol *proto);
53
54/* Note: must not be declared <const> as its list will be overwritten */
55static struct protocol proto_unix = {
56 .name = "unix_stream",
57 .sock_domain = PF_UNIX,
58 .sock_type = SOCK_STREAM,
59 .sock_prot = 0,
60 .sock_family = AF_UNIX,
61 .sock_addrlen = sizeof(struct sockaddr_un),
62 .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),/* path len */
Willy Tarreaueb472682010-05-28 18:46:57 +020063 .accept = &stream_sock_accept,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010064 .read = &stream_sock_read,
65 .write = &stream_sock_write,
Emeric Bruncf20bf12010-10-22 16:06:11 +020066 .bind = uxst_bind_listener,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010067 .bind_all = uxst_bind_listeners,
68 .unbind_all = uxst_unbind_listeners,
69 .enable_all = enable_all_listeners,
70 .disable_all = disable_all_listeners,
71 .listeners = LIST_HEAD_INIT(proto_unix.listeners),
72 .nb_listeners = 0,
73};
74
Willy Tarreaudabf2e22007-10-28 21:59:24 +010075/********************************
76 * 1) low-level socket functions
77 ********************************/
78
79
Willy Tarreau92fb9832007-10-16 17:34:28 +020080/* This function creates a named PF_UNIX stream socket at address <path>. Note
Willy Tarreaue6ad2b12007-10-18 12:45:54 +020081 * that the path cannot be NULL nor empty. <uid> and <gid> different of -1 will
82 * be used to change the socket owner. If <mode> is not 0, it will be used to
83 * restrict access to the socket. While it is known not to be portable on every
84 * OS, it's still useful where it works.
Willy Tarreau92fb9832007-10-16 17:34:28 +020085 * It returns the assigned file descriptor, or -1 in the event of an error.
86 */
Emeric Bruncf20bf12010-10-22 16:06:11 +020087static int create_uxst_socket(const char *path, uid_t uid, gid_t gid, mode_t mode, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +020088{
89 char tempname[MAXPATHLEN];
90 char backname[MAXPATHLEN];
91 struct sockaddr_un addr;
92
93 int ret, sock;
94
95 /* 1. create socket names */
96 if (!path[0]) {
Emeric Bruncf20bf12010-10-22 16:06:11 +020097 if (errmsg && errlen)
98 snprintf(errmsg, errlen, "Invalid empty name for a UNIX socket");
Willy Tarreau92fb9832007-10-16 17:34:28 +020099 goto err_return;
100 }
101
102 ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
103 if (ret < 0 || ret >= MAXPATHLEN) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200104 if (errmsg && errlen)
105 snprintf(errmsg, errlen, "name too long for UNIX socket (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200106 goto err_return;
107 }
108
109 ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
110 if (ret < 0 || ret >= MAXPATHLEN) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200111 if (errmsg && errlen)
112 snprintf(errmsg, errlen, "name too long for UNIX socket (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200113 goto err_return;
114 }
115
116 /* 2. clean existing orphaned entries */
117 if (unlink(tempname) < 0 && errno != ENOENT) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200118 if (errmsg && errlen)
119 snprintf(errmsg, errlen, "error when trying to unlink previous UNIX socket (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200120 goto err_return;
121 }
122
123 if (unlink(backname) < 0 && errno != ENOENT) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200124 if (errmsg && errlen)
125 snprintf(errmsg, errlen, "error when trying to unlink previous UNIX socket (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200126 goto err_return;
127 }
128
129 /* 3. backup existing socket */
130 if (link(path, backname) < 0 && errno != ENOENT) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200131 if (errmsg && errlen)
132 snprintf(errmsg, errlen, "error when trying to preserve previous UNIX socket (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200133 goto err_return;
134 }
135
136 /* 4. prepare new socket */
137 addr.sun_family = AF_UNIX;
138 strncpy(addr.sun_path, tempname, sizeof(addr.sun_path));
139 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
140
141 sock = socket(PF_UNIX, SOCK_STREAM, 0);
142 if (sock < 0) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200143 if (errmsg && errlen)
144 snprintf(errmsg, errlen, "cannot create socket for UNIX listener (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200145 goto err_unlink_back;
146 }
147
148 if (sock >= global.maxsock) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200149 if (errmsg && errlen)
150 snprintf(errmsg, errlen, "socket(): not enough free sockets for UNIX listener (%s). Raise -n argument", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200151 goto err_unlink_temp;
152 }
153
154 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200155 if (errmsg && errlen)
156 snprintf(errmsg, errlen, "cannot make UNIX socket non-blocking");
Willy Tarreau92fb9832007-10-16 17:34:28 +0200157 goto err_unlink_temp;
158 }
159
160 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
161 /* note that bind() creates the socket <tempname> on the file system */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200162 if (errmsg && errlen)
163 snprintf(errmsg, errlen, "cannot bind socket for UNIX listener (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200164 goto err_unlink_temp;
165 }
166
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200167 if (((uid != -1 || gid != -1) && (chown(tempname, uid, gid) == -1)) ||
168 (mode != 0 && chmod(tempname, mode) == -1)) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200169 if (errmsg && errlen)
170 snprintf(errmsg, errlen, "cannot change UNIX socket ownership (%s)", path);
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200171 goto err_unlink_temp;
172 }
173
Willy Tarreau92fb9832007-10-16 17:34:28 +0200174 if (listen(sock, 0) < 0) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200175 if (errmsg && errlen)
176 snprintf(errmsg, errlen, "cannot listen to socket for UNIX listener (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200177 goto err_unlink_temp;
178 }
179
180 /* 5. install.
181 * Point of no return: we are ready, we'll switch the sockets. We don't
182 * fear loosing the socket <path> because we have a copy of it in
183 * backname.
184 */
185 if (rename(tempname, path) < 0) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200186 if (errmsg && errlen)
187 snprintf(errmsg, errlen, "cannot switch final and temporary sockets for UNIX listener (%s)", path);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200188 goto err_rename;
189 }
190
191 /* 6. cleanup */
192 unlink(backname); /* no need to keep this one either */
193
194 return sock;
195
196 err_rename:
197 ret = rename(backname, path);
198 if (ret < 0 && errno == ENOENT)
199 unlink(path);
200 err_unlink_temp:
201 unlink(tempname);
202 close(sock);
203 err_unlink_back:
204 unlink(backname);
205 err_return:
206 return -1;
207}
208
209/* Tries to destroy the UNIX stream socket <path>. The socket must not be used
210 * anymore. It practises best effort, and no error is returned.
211 */
212static void destroy_uxst_socket(const char *path)
213{
214 struct sockaddr_un addr;
215 int sock, ret;
216
217 /* We might have been chrooted, so we may not be able to access the
218 * socket. In order to avoid bothering the other end, we connect with a
219 * wrong protocol, namely SOCK_DGRAM. The return code from connect()
220 * is enough to know if the socket is still live or not. If it's live
221 * in mode SOCK_STREAM, we get EPROTOTYPE or anything else but not
222 * ECONNREFUSED. In this case, we do not touch it because it's used
223 * by some other process.
224 */
225 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
226 if (sock < 0)
227 return;
228
229 addr.sun_family = AF_UNIX;
230 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
Willy Tarreau10ae5482007-10-18 16:15:52 +0200231 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200232 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
233 if (ret < 0 && errno == ECONNREFUSED) {
234 /* Connect failed: the socket still exists but is not used
235 * anymore. Let's remove this socket now.
236 */
237 unlink(path);
238 }
239 close(sock);
240}
241
242
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100243/********************************
244 * 2) listener-oriented functions
245 ********************************/
246
247
248/* This function creates the UNIX socket associated to the listener. It changes
249 * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
250 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
251 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200252static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen)
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100253{
254 int fd;
Willy Tarreaub1356cf2008-12-07 16:06:43 +0100255
Emeric Bruncf20bf12010-10-22 16:06:11 +0200256 /* ensure we never return garbage */
257 if (errmsg && errlen)
258 *errmsg = 0;
259
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100260 if (listener->state != LI_ASSIGNED)
261 return ERR_NONE; /* already bound */
262
263 fd = create_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path,
264 listener->perm.ux.uid,
265 listener->perm.ux.gid,
Emeric Bruncf20bf12010-10-22 16:06:11 +0200266 listener->perm.ux.mode, errmsg, errlen);
267 if (fd == -1) {
268 return ERR_FATAL | ERR_ALERT;
269 }
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100270 /* the socket is now listening */
271 listener->fd = fd;
272 listener->state = LI_LISTEN;
273
274 /* the function for the accept() event */
275 fd_insert(fd);
Willy Tarreaueb472682010-05-28 18:46:57 +0200276 fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100277 fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
278 fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL;
Willy Tarreaueabf3132008-08-29 23:36:51 +0200279 fdtab[fd].owner = listener; /* reference the listener instead of a task */
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100280 fdtab[fd].state = FD_STLISTEN;
Willy Tarreau8d5d77e2009-10-18 07:25:52 +0200281 fdinfo[fd].peeraddr = NULL;
282 fdinfo[fd].peerlen = 0;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100283 return ERR_NONE;
284}
285
286/* This function closes the UNIX sockets for the specified listener.
287 * The listener enters the LI_ASSIGNED state. It always returns ERR_NONE.
288 */
289static int uxst_unbind_listener(struct listener *listener)
290{
291 if (listener->state == LI_READY)
292 EV_FD_CLR(listener->fd, DIR_RD);
293
294 if (listener->state >= LI_LISTEN) {
Willy Tarreau8eebe5e2007-10-28 22:07:08 +0100295 fd_delete(listener->fd);
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100296 listener->state = LI_ASSIGNED;
297 destroy_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path);
298 }
299 return ERR_NONE;
300}
301
302/* Add a listener to the list of unix stream listeners. The listener's state
303 * is automatically updated from LI_INIT to LI_ASSIGNED. The number of
304 * listeners is updated. This is the function to use to add a new listener.
305 */
306void uxst_add_listener(struct listener *listener)
307{
308 if (listener->state != LI_INIT)
309 return;
310 listener->state = LI_ASSIGNED;
311 listener->proto = &proto_unix;
312 LIST_ADDQ(&proto_unix.listeners, &listener->proto_list);
313 proto_unix.nb_listeners++;
314}
315
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100316/********************************
317 * 3) protocol-oriented functions
318 ********************************/
319
320
Willy Tarreau92fb9832007-10-16 17:34:28 +0200321/* This function creates all UNIX sockets bound to the protocol entry <proto>.
322 * It is intended to be used as the protocol's bind_all() function.
323 * The sockets will be registered but not added to any fd_set, in order not to
324 * loose them across the fork(). A call to uxst_enable_listeners() is needed
325 * to complete initialization.
326 *
327 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
328 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200329static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200330{
331 struct listener *listener;
332 int err = ERR_NONE;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200333
334 list_for_each_entry(listener, &proto->listeners, proto_list) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200335 err |= uxst_bind_listener(listener, errmsg, errlen);
336 if (err & ERR_ABORT)
337 break;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200338 }
Willy Tarreau92fb9832007-10-16 17:34:28 +0200339 return err;
340}
341
Willy Tarreau92fb9832007-10-16 17:34:28 +0200342
343/* This function stops all listening UNIX sockets bound to the protocol
344 * <proto>. It does not detaches them from the protocol.
345 * It always returns ERR_NONE.
346 */
347static int uxst_unbind_listeners(struct protocol *proto)
348{
349 struct listener *listener;
350
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100351 list_for_each_entry(listener, &proto->listeners, proto_list)
352 uxst_unbind_listener(listener);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200353 return ERR_NONE;
354}
355
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100356
357/********************************
358 * 4) high-level functions
359 ********************************/
360
Willy Tarreau92fb9832007-10-16 17:34:28 +0200361__attribute__((constructor))
362static void __uxst_protocol_init(void)
363{
364 protocol_register(&proto_unix);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200365}
366
367
368/*
369 * Local variables:
370 * c-indent-level: 8
371 * c-basic-offset: 8
372 * End:
373 */