blob: 732fd2206a76f032621014564d696ff62d9c76ff [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 Tarreau92fb9832007-10-16 17:34:28 +020042#include <proto/stream_sock.h>
43#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 Tarreaueb472682010-05-28 18:46:57 +020058 .accept = &stream_sock_accept,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010059 .read = &stream_sock_read,
60 .write = &stream_sock_write,
Emeric Bruncf20bf12010-10-22 16:06:11 +020061 .bind = uxst_bind_listener,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010062 .bind_all = uxst_bind_listeners,
63 .unbind_all = uxst_unbind_listeners,
64 .enable_all = enable_all_listeners,
65 .disable_all = disable_all_listeners,
66 .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
74
Willy Tarreau92fb9832007-10-16 17:34:28 +020075/* This function creates a named PF_UNIX stream socket at address <path>. Note
Willy Tarreaue6ad2b12007-10-18 12:45:54 +020076 * that the path cannot be NULL nor empty. <uid> and <gid> different of -1 will
77 * be used to change the socket owner. If <mode> is not 0, it will be used to
78 * restrict access to the socket. While it is known not to be portable on every
79 * OS, it's still useful where it works.
Willy Tarreau92fb9832007-10-16 17:34:28 +020080 * It returns the assigned file descriptor, or -1 in the event of an error.
81 */
Cyril Bontée4cbbe22010-11-14 17:03:18 +010082static int create_uxst_socket(const char *path, uid_t uid, gid_t gid, mode_t mode, int backlog, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +020083{
84 char tempname[MAXPATHLEN];
85 char backname[MAXPATHLEN];
86 struct sockaddr_un addr;
Willy Tarreaub40dc942010-11-07 12:10:51 +010087 const char *msg = NULL;
Willy Tarreau92fb9832007-10-16 17:34:28 +020088
89 int ret, sock;
90
91 /* 1. create socket names */
92 if (!path[0]) {
Willy Tarreaub40dc942010-11-07 12:10:51 +010093 msg = "Invalid empty name for a UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +020094 goto err_return;
95 }
96
97 ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
98 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +010099 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200100 goto err_return;
101 }
102
103 ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
104 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100105 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200106 goto err_return;
107 }
108
109 /* 2. clean existing orphaned entries */
110 if (unlink(tempname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100111 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200112 goto err_return;
113 }
114
115 if (unlink(backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100116 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200117 goto err_return;
118 }
119
120 /* 3. backup existing socket */
121 if (link(path, backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100122 msg = "error when trying to preserve previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200123 goto err_return;
124 }
125
126 /* 4. prepare new socket */
127 addr.sun_family = AF_UNIX;
128 strncpy(addr.sun_path, tempname, sizeof(addr.sun_path));
129 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
130
131 sock = socket(PF_UNIX, SOCK_STREAM, 0);
132 if (sock < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100133 msg = "cannot create UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200134 goto err_unlink_back;
135 }
136
137 if (sock >= global.maxsock) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100138 msg = "socket(): not enough free sockets, raise -n argument";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200139 goto err_unlink_temp;
140 }
141
142 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100143 msg = "cannot make UNIX socket non-blocking";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200144 goto err_unlink_temp;
145 }
146
147 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
148 /* note that bind() creates the socket <tempname> on the file system */
Willy Tarreaub40dc942010-11-07 12:10:51 +0100149 msg = "cannot bind UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200150 goto err_unlink_temp;
151 }
152
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200153 if (((uid != -1 || gid != -1) && (chown(tempname, uid, gid) == -1)) ||
154 (mode != 0 && chmod(tempname, mode) == -1)) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100155 msg = "cannot change UNIX socket ownership";
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200156 goto err_unlink_temp;
157 }
158
Cyril Bontée4cbbe22010-11-14 17:03:18 +0100159 if (listen(sock, backlog) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100160 msg = "cannot listen to UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200161 goto err_unlink_temp;
162 }
163
164 /* 5. install.
165 * Point of no return: we are ready, we'll switch the sockets. We don't
166 * fear loosing the socket <path> because we have a copy of it in
167 * backname.
168 */
169 if (rename(tempname, path) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100170 msg = "cannot switch final and temporary UNIX sockets";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200171 goto err_rename;
172 }
173
174 /* 6. cleanup */
175 unlink(backname); /* no need to keep this one either */
176
177 return sock;
178
179 err_rename:
180 ret = rename(backname, path);
181 if (ret < 0 && errno == ENOENT)
182 unlink(path);
183 err_unlink_temp:
184 unlink(tempname);
185 close(sock);
186 err_unlink_back:
187 unlink(backname);
188 err_return:
Willy Tarreaub40dc942010-11-07 12:10:51 +0100189 if (msg && errlen)
190 snprintf(errmsg, errlen, "%s [%s]", msg, path);
191
Willy Tarreau92fb9832007-10-16 17:34:28 +0200192 return -1;
193}
194
195/* Tries to destroy the UNIX stream socket <path>. The socket must not be used
196 * anymore. It practises best effort, and no error is returned.
197 */
198static void destroy_uxst_socket(const char *path)
199{
200 struct sockaddr_un addr;
201 int sock, ret;
202
203 /* We might have been chrooted, so we may not be able to access the
204 * socket. In order to avoid bothering the other end, we connect with a
205 * wrong protocol, namely SOCK_DGRAM. The return code from connect()
206 * is enough to know if the socket is still live or not. If it's live
207 * in mode SOCK_STREAM, we get EPROTOTYPE or anything else but not
208 * ECONNREFUSED. In this case, we do not touch it because it's used
209 * by some other process.
210 */
211 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
212 if (sock < 0)
213 return;
214
215 addr.sun_family = AF_UNIX;
216 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
Willy Tarreau10ae5482007-10-18 16:15:52 +0200217 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200218 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
219 if (ret < 0 && errno == ECONNREFUSED) {
220 /* Connect failed: the socket still exists but is not used
221 * anymore. Let's remove this socket now.
222 */
223 unlink(path);
224 }
225 close(sock);
226}
227
228
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100229/********************************
230 * 2) listener-oriented functions
231 ********************************/
232
233
234/* This function creates the UNIX socket associated to the listener. It changes
235 * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
236 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
237 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200238static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen)
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100239{
240 int fd;
Willy Tarreaub1356cf2008-12-07 16:06:43 +0100241
Emeric Bruncf20bf12010-10-22 16:06:11 +0200242 /* ensure we never return garbage */
243 if (errmsg && errlen)
244 *errmsg = 0;
245
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100246 if (listener->state != LI_ASSIGNED)
247 return ERR_NONE; /* already bound */
248
249 fd = create_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path,
250 listener->perm.ux.uid,
251 listener->perm.ux.gid,
Cyril Bontée4cbbe22010-11-14 17:03:18 +0100252 listener->perm.ux.mode,
253 listener->backlog ? listener->backlog : listener->maxconn,
254 errmsg, errlen);
Emeric Bruncf20bf12010-10-22 16:06:11 +0200255 if (fd == -1) {
256 return ERR_FATAL | ERR_ALERT;
257 }
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100258 /* the socket is now listening */
259 listener->fd = fd;
260 listener->state = LI_LISTEN;
261
262 /* the function for the accept() event */
263 fd_insert(fd);
Willy Tarreaueb472682010-05-28 18:46:57 +0200264 fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100265 fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
266 fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL;
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;
272}
273
274/* This function closes the UNIX sockets for the specified listener.
275 * The listener enters the LI_ASSIGNED state. It always returns ERR_NONE.
276 */
277static int uxst_unbind_listener(struct listener *listener)
278{
279 if (listener->state == LI_READY)
280 EV_FD_CLR(listener->fd, DIR_RD);
281
282 if (listener->state >= LI_LISTEN) {
Willy Tarreau8eebe5e2007-10-28 22:07:08 +0100283 fd_delete(listener->fd);
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100284 listener->state = LI_ASSIGNED;
285 destroy_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path);
286 }
287 return ERR_NONE;
288}
289
290/* Add a listener to the list of unix stream listeners. The listener's state
291 * is automatically updated from LI_INIT to LI_ASSIGNED. The number of
292 * listeners is updated. This is the function to use to add a new listener.
293 */
294void uxst_add_listener(struct listener *listener)
295{
296 if (listener->state != LI_INIT)
297 return;
298 listener->state = LI_ASSIGNED;
299 listener->proto = &proto_unix;
300 LIST_ADDQ(&proto_unix.listeners, &listener->proto_list);
301 proto_unix.nb_listeners++;
302}
303
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100304/********************************
305 * 3) protocol-oriented functions
306 ********************************/
307
308
Willy Tarreau92fb9832007-10-16 17:34:28 +0200309/* This function creates all UNIX sockets bound to the protocol entry <proto>.
310 * It is intended to be used as the protocol's bind_all() function.
311 * The sockets will be registered but not added to any fd_set, in order not to
312 * loose them across the fork(). A call to uxst_enable_listeners() is needed
313 * to complete initialization.
314 *
315 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
316 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200317static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200318{
319 struct listener *listener;
320 int err = ERR_NONE;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200321
322 list_for_each_entry(listener, &proto->listeners, proto_list) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200323 err |= uxst_bind_listener(listener, errmsg, errlen);
324 if (err & ERR_ABORT)
325 break;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200326 }
Willy Tarreau92fb9832007-10-16 17:34:28 +0200327 return err;
328}
329
Willy Tarreau92fb9832007-10-16 17:34:28 +0200330
331/* This function stops all listening UNIX sockets bound to the protocol
332 * <proto>. It does not detaches them from the protocol.
333 * It always returns ERR_NONE.
334 */
335static int uxst_unbind_listeners(struct protocol *proto)
336{
337 struct listener *listener;
338
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100339 list_for_each_entry(listener, &proto->listeners, proto_list)
340 uxst_unbind_listener(listener);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200341 return ERR_NONE;
342}
343
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100344
345/********************************
346 * 4) high-level functions
347 ********************************/
348
Willy Tarreau92fb9832007-10-16 17:34:28 +0200349__attribute__((constructor))
350static void __uxst_protocol_init(void)
351{
352 protocol_register(&proto_unix);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200353}
354
355
356/*
357 * Local variables:
358 * c-indent-level: 8
359 * c-basic-offset: 8
360 * End:
361 */