blob: e4aaeedfeb4f814d78415e32893a08b92c4eb671 [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/task.h>
43
Emeric Bruncf20bf12010-10-22 16:06:11 +020044static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
45static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
Willy Tarreaudabf2e22007-10-28 21:59:24 +010046static int uxst_unbind_listeners(struct protocol *proto);
47
48/* Note: must not be declared <const> as its list will be overwritten */
49static struct protocol proto_unix = {
50 .name = "unix_stream",
51 .sock_domain = PF_UNIX,
52 .sock_type = SOCK_STREAM,
53 .sock_prot = 0,
54 .sock_family = AF_UNIX,
55 .sock_addrlen = sizeof(struct sockaddr_un),
56 .l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),/* path len */
Willy Tarreaubbebbbf2012-05-07 21:22:09 +020057 .accept = &listener_accept,
Emeric Bruncf20bf12010-10-22 16:06:11 +020058 .bind = uxst_bind_listener,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010059 .bind_all = uxst_bind_listeners,
60 .unbind_all = uxst_unbind_listeners,
61 .enable_all = enable_all_listeners,
62 .disable_all = disable_all_listeners,
Willy Tarreau59b94792012-05-11 16:16:40 +020063 .get_src = uxst_get_src,
64 .get_dst = uxst_get_dst,
Willy Tarreaudabf2e22007-10-28 21:59:24 +010065 .listeners = LIST_HEAD_INIT(proto_unix.listeners),
66 .nb_listeners = 0,
67};
68
Willy Tarreaudabf2e22007-10-28 21:59:24 +010069/********************************
70 * 1) low-level socket functions
71 ********************************/
72
Willy Tarreau59b94792012-05-11 16:16:40 +020073/*
74 * Retrieves the source address for the socket <fd>, with <dir> indicating
75 * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
76 * success, -1 in case of error. The socket's source address is stored in
77 * <sa> for <salen> bytes.
78 */
79int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
80{
81 if (dir)
82 return getsockname(fd, sa, &salen);
83 else
84 return getpeername(fd, sa, &salen);
85}
86
87
88/*
89 * Retrieves the original destination address for the socket <fd>, with <dir>
90 * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
91 * case of success, -1 in case of error. The socket's source address is stored
92 * in <sa> for <salen> bytes.
93 */
94int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
95{
96 if (dir)
97 return getpeername(fd, sa, &salen);
98 else
99 return getsockname(fd, sa, &salen);
100}
101
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100102
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100103/* Tries to destroy the UNIX stream socket <path>. The socket must not be used
104 * anymore. It practises best effort, and no error is returned.
105 */
106static void destroy_uxst_socket(const char *path)
107{
108 struct sockaddr_un addr;
109 int sock, ret;
110
111 /* We might have been chrooted, so we may not be able to access the
112 * socket. In order to avoid bothering the other end, we connect with a
113 * wrong protocol, namely SOCK_DGRAM. The return code from connect()
114 * is enough to know if the socket is still live or not. If it's live
115 * in mode SOCK_STREAM, we get EPROTOTYPE or anything else but not
116 * ECONNREFUSED. In this case, we do not touch it because it's used
117 * by some other process.
118 */
119 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
120 if (sock < 0)
121 return;
122
123 addr.sun_family = AF_UNIX;
124 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
125 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
126 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
127 if (ret < 0 && errno == ECONNREFUSED) {
128 /* Connect failed: the socket still exists but is not used
129 * anymore. Let's remove this socket now.
130 */
131 unlink(path);
132 }
133 close(sock);
134}
135
136
137/********************************
138 * 2) listener-oriented functions
139 ********************************/
140
141
142/* This function creates a UNIX socket associated to the listener. It changes
143 * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
144 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
Willy Tarreau92fb9832007-10-16 17:34:28 +0200145 */
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100146static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200147{
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100148 int fd;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200149 char tempname[MAXPATHLEN];
150 char backname[MAXPATHLEN];
151 struct sockaddr_un addr;
Willy Tarreaub40dc942010-11-07 12:10:51 +0100152 const char *msg = NULL;
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100153 const char *path;
154
155 int ret;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200156
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100157 /* ensure we never return garbage */
158 if (errmsg && errlen)
159 *errmsg = 0;
160
161 if (listener->state != LI_ASSIGNED)
162 return ERR_NONE; /* already bound */
163
164 path = ((struct sockaddr_un *)&listener->addr)->sun_path;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200165
166 /* 1. create socket names */
167 if (!path[0]) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100168 msg = "Invalid empty name for a UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200169 goto err_return;
170 }
171
172 ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
173 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100174 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200175 goto err_return;
176 }
177
178 ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
179 if (ret < 0 || ret >= MAXPATHLEN) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100180 msg = "name too long for UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200181 goto err_return;
182 }
183
184 /* 2. clean existing orphaned entries */
185 if (unlink(tempname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100186 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200187 goto err_return;
188 }
189
190 if (unlink(backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100191 msg = "error when trying to unlink previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200192 goto err_return;
193 }
194
195 /* 3. backup existing socket */
196 if (link(path, backname) < 0 && errno != ENOENT) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100197 msg = "error when trying to preserve previous UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200198 goto err_return;
199 }
200
201 /* 4. prepare new socket */
202 addr.sun_family = AF_UNIX;
203 strncpy(addr.sun_path, tempname, sizeof(addr.sun_path));
204 addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
205
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100206 fd = socket(PF_UNIX, SOCK_STREAM, 0);
207 if (fd < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100208 msg = "cannot create UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200209 goto err_unlink_back;
210 }
211
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100212 if (fd >= global.maxsock) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100213 msg = "socket(): not enough free sockets, raise -n argument";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200214 goto err_unlink_temp;
215 }
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100216
217 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100218 msg = "cannot make UNIX socket non-blocking";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200219 goto err_unlink_temp;
220 }
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100221
222 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
Willy Tarreau92fb9832007-10-16 17:34:28 +0200223 /* note that bind() creates the socket <tempname> on the file system */
Willy Tarreaub40dc942010-11-07 12:10:51 +0100224 msg = "cannot bind UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200225 goto err_unlink_temp;
226 }
227
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100228 /* <uid> and <gid> different of -1 will be used to change the socket owner.
229 * If <mode> is not 0, it will be used to restrict access to the socket.
230 * While it is known not to be portable on every OS, it's still useful
231 * where it works.
232 */
233 if (((listener->perm.ux.uid != -1 || listener->perm.ux.gid != -1) &&
234 (chown(tempname, listener->perm.ux.uid, listener->perm.ux.gid) == -1)) ||
235 (listener->perm.ux.mode != 0 && chmod(tempname, listener->perm.ux.mode) == -1)) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100236 msg = "cannot change UNIX socket ownership";
Willy Tarreaue6ad2b12007-10-18 12:45:54 +0200237 goto err_unlink_temp;
238 }
239
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100240 if (listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100241 msg = "cannot listen to UNIX socket";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200242 goto err_unlink_temp;
243 }
244
245 /* 5. install.
246 * Point of no return: we are ready, we'll switch the sockets. We don't
247 * fear loosing the socket <path> because we have a copy of it in
248 * backname.
249 */
250 if (rename(tempname, path) < 0) {
Willy Tarreaub40dc942010-11-07 12:10:51 +0100251 msg = "cannot switch final and temporary UNIX sockets";
Willy Tarreau92fb9832007-10-16 17:34:28 +0200252 goto err_rename;
253 }
254
255 /* 6. cleanup */
256 unlink(backname); /* no need to keep this one either */
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 Tarreauaece46a2012-07-06 12:25:58 +0200264 fdtab[fd].iocb = listener->proto->accept;
Willy Tarreaueabf3132008-08-29 23:36:51 +0200265 fdtab[fd].owner = listener; /* reference the listener instead of a task */
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100266 return ERR_NONE;
Cyril Bonté1f5848a2010-11-14 17:03:19 +0100267 err_rename:
268 ret = rename(backname, path);
269 if (ret < 0 && errno == ENOENT)
270 unlink(path);
271 err_unlink_temp:
272 unlink(tempname);
273 close(fd);
274 err_unlink_back:
275 unlink(backname);
276 err_return:
277 if (msg && errlen)
278 snprintf(errmsg, errlen, "%s [%s]", msg, path);
279 return ERR_FATAL | ERR_ALERT;
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100280}
281
282/* This function closes the UNIX sockets for the specified listener.
283 * The listener enters the LI_ASSIGNED state. It always returns ERR_NONE.
284 */
285static int uxst_unbind_listener(struct listener *listener)
286{
Willy Tarreaube58c382011-07-24 18:28:10 +0200287 if (listener->state > LI_ASSIGNED) {
288 unbind_listener(listener);
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100289 destroy_uxst_socket(((struct sockaddr_un *)&listener->addr)->sun_path);
290 }
291 return ERR_NONE;
292}
293
294/* Add a listener to the list of unix stream listeners. The listener's state
295 * is automatically updated from LI_INIT to LI_ASSIGNED. The number of
296 * listeners is updated. This is the function to use to add a new listener.
297 */
298void uxst_add_listener(struct listener *listener)
299{
300 if (listener->state != LI_INIT)
301 return;
302 listener->state = LI_ASSIGNED;
303 listener->proto = &proto_unix;
304 LIST_ADDQ(&proto_unix.listeners, &listener->proto_list);
305 proto_unix.nb_listeners++;
306}
307
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100308/********************************
309 * 3) protocol-oriented functions
310 ********************************/
311
312
Willy Tarreau92fb9832007-10-16 17:34:28 +0200313/* This function creates all UNIX sockets bound to the protocol entry <proto>.
314 * It is intended to be used as the protocol's bind_all() function.
315 * The sockets will be registered but not added to any fd_set, in order not to
316 * loose them across the fork(). A call to uxst_enable_listeners() is needed
317 * to complete initialization.
318 *
319 * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
320 */
Emeric Bruncf20bf12010-10-22 16:06:11 +0200321static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
Willy Tarreau92fb9832007-10-16 17:34:28 +0200322{
323 struct listener *listener;
324 int err = ERR_NONE;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200325
326 list_for_each_entry(listener, &proto->listeners, proto_list) {
Emeric Bruncf20bf12010-10-22 16:06:11 +0200327 err |= uxst_bind_listener(listener, errmsg, errlen);
328 if (err & ERR_ABORT)
329 break;
Willy Tarreau92fb9832007-10-16 17:34:28 +0200330 }
Willy Tarreau92fb9832007-10-16 17:34:28 +0200331 return err;
332}
333
Willy Tarreau92fb9832007-10-16 17:34:28 +0200334
335/* This function stops all listening UNIX sockets bound to the protocol
336 * <proto>. It does not detaches them from the protocol.
337 * It always returns ERR_NONE.
338 */
339static int uxst_unbind_listeners(struct protocol *proto)
340{
341 struct listener *listener;
342
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100343 list_for_each_entry(listener, &proto->listeners, proto_list)
344 uxst_unbind_listener(listener);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200345 return ERR_NONE;
346}
347
Willy Tarreaudabf2e22007-10-28 21:59:24 +0100348
349/********************************
350 * 4) high-level functions
351 ********************************/
352
Willy Tarreau92fb9832007-10-16 17:34:28 +0200353__attribute__((constructor))
354static void __uxst_protocol_init(void)
355{
356 protocol_register(&proto_unix);
Willy Tarreau92fb9832007-10-16 17:34:28 +0200357}
358
359
360/*
361 * Local variables:
362 * c-indent-level: 8
363 * c-basic-offset: 8
364 * End:
365 */