xref: /minix/minix/net/uds/uds.c (revision 90b80121)
1 /* UNIX Domain Sockets - uds.c - socket management */
2 
3 #include "uds.h"
4 
5 static struct udssock uds_array[NR_UDSSOCK];
6 static TAILQ_HEAD(uds_freelist, udssock) uds_freelist;
7 static unsigned int uds_in_use;
8 static int uds_running;
9 
10 static const struct sockevent_ops uds_ops;
11 
12 static SLIST_HEAD(udshash, udssock) udshash[UDSHASH_SLOTS];
13 
14 /*
15  * Initialize file-to-socket hash table.
16  */
17 static void
18 udshash_init(void)
19 {
20 	unsigned int slot;
21 
22 	for (slot = 0; slot < __arraycount(udshash); slot++)
23 		SLIST_INIT(&udshash[slot]);
24 }
25 
26 /*
27  * Return a hash table slot number for the given <dev,ino> pair.
28  */
29 static unsigned int
30 udshash_slot(dev_t dev, ino_t ino)
31 {
32 
33 	assert(dev != NO_DEV);
34 	assert(ino != 0);
35 
36 	/*
37 	 * Effectively combining two 64-bit numbers into a single 6-or-so-bit
38 	 * hash is not too easy.  This hash function is probably among the
39 	 * worst options.  Then again it is not all that critical as we are not
40 	 * expecting that many bound UDS sockets in the system anyway.
41 	 */
42 	return (unsigned int)(dev ^ ino) % UDSHASH_SLOTS;
43 }
44 
45 /*
46  * Look for a socket that is bound to the given <dev,ino> pair.  Return a
47  * pointer to the socket if found, or NULL otherwise.
48  */
49 static struct udssock *
50 udshash_get(dev_t dev, ino_t ino)
51 {
52 	struct udssock *uds;
53 	unsigned int slot;
54 
55 	slot = udshash_slot(dev, ino);
56 
57 	SLIST_FOREACH(uds, &udshash[slot], uds_hash) {
58 		if (uds->uds_dev == dev && uds->uds_ino == ino)
59 			return uds;
60 	}
61 
62 	return NULL;
63 }
64 
65 /*
66  * Add a socket to the file-to-socket hash table.  The socket must have its
67  * device and inode fields set, and must not be in the hash table already.
68  */
69 static void
70 udshash_add(struct udssock * uds)
71 {
72 	unsigned int slot;
73 
74 	slot = udshash_slot(uds->uds_dev, uds->uds_ino);
75 
76 	SLIST_INSERT_HEAD(&udshash[slot], uds, uds_hash);
77 }
78 
79 /*
80  * Remove a socket from the file-to-socket hash table.  The socket must be in
81  * the hash table.
82  */
83 static void
84 udshash_del(struct udssock * uds)
85 {
86 	unsigned int slot;
87 
88 	slot = udshash_slot(uds->uds_dev, uds->uds_ino);
89 
90 	/* This macro is O(n). */
91 	SLIST_REMOVE(&udshash[slot], uds, udssock, uds_hash);
92 }
93 
94 /*
95  * Return the socket identifier for the given UDS socket object.
96  */
97 sockid_t
98 uds_get_id(struct udssock * uds)
99 {
100 
101 	return (sockid_t)(uds - uds_array);
102 }
103 
104 /*
105  * Given either NULL or a previously returned socket, return the next in-use
106  * UDS socket of the given socket type, or NULL if there are no more matches.
107  * The sockets are returned in random order, but each matching socket is
108  * returned exactly once (until any socket is allocated or freed).
109  */
110 struct udssock *
111 uds_enum(struct udssock * prev, int type)
112 {
113 	sockid_t id;
114 
115 	if (prev != NULL)
116 		id = uds_get_id(prev) + 1;
117 	else
118 		id = 0;
119 
120 	for (; id < NR_UDSSOCK; id++)
121 		if ((uds_array[id].uds_flags & UDSF_IN_USE) &&
122 		    uds_get_type(&uds_array[id]) == type)
123 			return &uds_array[id];
124 
125 	return NULL;
126 }
127 
128 /*
129  * Invalidate credentials on the socket.
130  */
131 static void
132 uds_clear_cred(struct udssock * uds)
133 {
134 
135 	uds->uds_cred.unp_pid = -1;
136 	uds->uds_cred.unp_euid = -1;
137 	uds->uds_cred.unp_egid = -1;
138 }
139 
140 /*
141  * Obtain the credentials (process, user, and group ID) of the given user
142  * endpoint and associate them with the socket for later retrieval.  It is
143  * important to note that this information is obtained once at connect time,
144  * and never updated later.  The party receiving the credentials must take this
145  * into account.
146  */
147 static void
148 uds_get_cred(struct udssock * uds, endpoint_t user_endpt)
149 {
150 	int r;
151 
152 	if ((uds->uds_cred.unp_pid = r = getepinfo(user_endpt,
153 	    &uds->uds_cred.unp_euid, &uds->uds_cred.unp_egid)) < 0) {
154 		printf("UDS: failed obtaining credentials of %d (%d)\n",
155 		    user_endpt, r);
156 
157 		uds_clear_cred(uds);
158 	}
159 }
160 
161 /*
162  * Allocate and initialize a UDS socket.  On succes, return OK with a pointer
163  * to the new socket in 'udsp'.  On failure, return a negative error code.
164  */
165 static int
166 uds_alloc(struct udssock ** udsp)
167 {
168 	struct udssock *uds;
169 	int r;
170 
171 	/* Allocate, initialize, and return a UNIX domain socket object. */
172 	if (TAILQ_EMPTY(&uds_freelist))
173 		return ENOBUFS;
174 
175 	uds = TAILQ_FIRST(&uds_freelist);
176 
177 	uds->uds_conn = NULL;		/* not connected */
178 	uds->uds_link = NULL;		/* not connecting or linked */
179 	uds->uds_queued = 0;
180 	uds->uds_flags = UDSF_IN_USE;	/* may be found through enumeration */
181 	uds->uds_pathlen = 0;		/* not bound: no path */
182 	uds->uds_dev = NO_DEV;		/* not hashed: no socket file device */
183 	uds->uds_ino = 0;		/* not hashed: no socket file inode */
184 	uds_clear_cred(uds);		/* no bind/connect-time credentials */
185 	TAILQ_INIT(&uds->uds_queue);	/* an empty queue */
186 
187 	if ((r = uds_io_setup(uds)) != OK)
188 		return r;
189 
190 	TAILQ_REMOVE(&uds_freelist, uds, uds_next);
191 
192 	assert(uds_in_use < NR_UDSSOCK);
193 	uds_in_use++;
194 
195 	*udsp = uds;
196 	return OK;
197 }
198 
199 /*
200  * Free a previously allocated socket.
201  */
202 static void
203 uds_free(struct sock * sock)
204 {
205 	struct udssock *uds = (struct udssock *)sock;
206 
207 	uds_io_cleanup(uds);
208 
209 	uds->uds_flags = 0;		/* no longer in use */
210 
211 	TAILQ_INSERT_HEAD(&uds_freelist, uds, uds_next);
212 
213 	assert(uds_in_use > 0);
214 	if (--uds_in_use == 0 && uds_running == FALSE)
215 		sef_cancel();
216 }
217 
218 /*
219  * Create a new socket.
220  */
221 static sockid_t
222 uds_socket(int domain, int type, int protocol, endpoint_t user_endpt __unused,
223 	struct sock ** sockp, const struct sockevent_ops ** ops)
224 {
225 	struct udssock *uds;
226 	int r;
227 
228 	dprintf(("UDS: socket(%d,%d,%d)\n", domain, type, protocol));
229 
230 	if (domain != PF_UNIX) {
231 		/* This means the service was configured incorrectly. */
232 		printf("UDS: got request for domain %d\n", domain);
233 
234 		return EAFNOSUPPORT;
235 	}
236 
237 	/* We support the following three socket types. */
238 	switch (type) {
239 	case SOCK_STREAM:
240 	case SOCK_SEQPACKET:
241 	case SOCK_DGRAM:
242 		break;
243 	default:
244 		return EPROTOTYPE;
245 	}
246 
247 	/*
248 	 * The PF_UNIX domain does not support particular protocols, so the
249 	 * given protocol must be zero (= anything that matches).
250 	 */
251 	if (protocol != UDSPROTO_UDS)
252 		return EPROTONOSUPPORT;
253 
254 	if ((r = uds_alloc(&uds)) != OK)
255 		return r;
256 
257 	dprintf(("UDS: socket returns %d\n", uds_get_id(uds)));
258 
259 	*sockp = &uds->uds_sock;
260 	*ops = &uds_ops;
261 	return uds_get_id(uds);
262 }
263 
264 /*
265  * Connect a pair of sockets.
266  */
267 static int
268 uds_pair(struct sock * sock1, struct sock * sock2, endpoint_t user_endpt)
269 {
270 	struct udssock *uds1 = (struct udssock *)sock1;
271 	struct udssock *uds2 = (struct udssock *)sock2;
272 
273 	dprintf(("UDS: pair(%d,%d)\n", uds_get_id(uds1), uds_get_id(uds2)));
274 
275 	/* Only connection-oriented types are acceptable. */
276 	if (uds_get_type(uds1) == SOCK_DGRAM)
277 		return EOPNOTSUPP;
278 
279 	/* Connect the sockets. */
280 	uds1->uds_conn = uds2;
281 	uds2->uds_conn = uds1;
282 	uds1->uds_flags |= UDSF_CONNECTED;
283 	uds2->uds_flags |= UDSF_CONNECTED;
284 
285 	/* Obtain the (same) credentials for both sides of the connection. */
286 	uds_get_cred(uds1, user_endpt);
287 	memcpy(&uds2->uds_cred, &uds1->uds_cred, sizeof(uds2->uds_cred));
288 
289 	return OK;
290 }
291 
292 /*
293  * Disconnect a UDS socket, notifying or freeing up the other end of the
294  * connection depending on whether the socket was linked, that is, on the
295  * accept queue of a listening socket.
296  */
297 static void
298 uds_disconnect(struct udssock * uds, int was_linked)
299 {
300 	struct udssock *conn;
301 
302 	assert(uds_is_connected(uds));
303 	assert(uds_has_conn(uds));
304 
305 	conn = uds->uds_conn;
306 
307 	assert(uds_is_connected(conn));
308 	assert(uds_has_conn(conn));
309 	assert(!uds_has_link(conn));
310 	assert(conn->uds_conn == uds);
311 
312 	/* Disconnect the sockets. */
313 	uds->uds_conn = NULL;
314 	conn->uds_conn = NULL;
315 
316 	/*
317 	 * If the given socket is linked, then it is a connected socket for
318 	 * which the other end has been created but not yet accepted.  In that
319 	 * case, the other end ('conn') will have to be freed up.  Otherwise,
320 	 * it is a regular user-created socket and we must properly transition
321 	 * it into disconnected state.
322 	 */
323 	if (!was_linked) {
324 		sockevent_raise(&conn->uds_sock, SEV_SEND | SEV_RECV);
325 
326 		/*
327 		 * Clear the peer credentials so that they will not be mistaken
328 		 * for having been obtained at bind time.
329 		 */
330 		uds_clear_cred(conn);
331 	} else
332 		sockevent_raise(&conn->uds_sock, SEV_CLOSE);
333 }
334 
335 /*
336  * Add the socket 'link' to the queue of the socket 'uds'.  This also implies
337  * that 'link's link socket is set to 'uds'.
338  */
339 static void
340 uds_add_queue(struct udssock * uds, struct udssock * link)
341 {
342 
343 	dprintf(("UDS: add_queue(%d,%d)\n",
344 	    uds_get_id(uds), uds_get_id(link)));
345 
346 	TAILQ_INSERT_TAIL(&uds->uds_queue, link, uds_next);
347 
348 	uds->uds_queued++;
349 	assert(uds->uds_queued != 0);
350 
351 	link->uds_link = uds;
352 }
353 
354 /*
355  * Remove the socket 'link' from the queue of the socket 'uds'.  This also
356  * reset 'link's link to NULL.
357  */
358 static void
359 uds_del_queue(struct udssock * uds, struct udssock * link)
360 {
361 
362 	dprintf(("UDS: del_queue(%d,%d)\n",
363 	    uds_get_id(uds), uds_get_id(link)));
364 
365 	assert(link->uds_link == uds);
366 
367 	TAILQ_REMOVE(&uds->uds_queue, link, uds_next);
368 
369 	assert(uds->uds_queued > 0);
370 	uds->uds_queued--;
371 
372 	link->uds_link = NULL;
373 }
374 
375 /*
376  * Remove all sockets from the queue of the socket 'uds', with the exception of
377  * 'except' if non-NULL.  Raise an ECONNRESET error on all removed sockets that
378  * are not equal to 'uds'.
379  */
380 static void
381 uds_clear_queue(struct udssock * uds, struct udssock * except)
382 {
383 	struct udssock *link, *tmp;
384 	int found;
385 
386 	dprintf(("UDS: clear_queue(%d,%d)\n",
387 	    uds_get_id(uds), (except != NULL) ? uds_get_id(except) : -1));
388 
389 	found = 0;
390 
391 	/*
392 	 * Abort all connecting sockets queued on this socket, except for the
393 	 * given exception, which may be NULL.
394 	 */
395 	TAILQ_FOREACH_SAFE(link, &uds->uds_queue, uds_next, tmp) {
396 		if (link == except) {
397 			found++;
398 
399 			continue;
400 		}
401 
402 		dprintf(("UDS: clear_queue removes %d\n", uds_get_id(link)));
403 
404 		assert(uds_get_type(link) == SOCK_DGRAM ||
405 		    uds_is_connecting(link) || uds_is_connected(link));
406 
407 		uds_del_queue(uds, link);
408 
409 		/*
410 		 * Generate an error only if the socket was not linked to
411 		 * itself (only datagram sockets can be linked to themselves).
412 		 * The error is not helpful for applications in that case.
413 		 */
414 		if (uds != link)
415 			sockevent_set_error(&link->uds_sock, ECONNRESET);
416 
417 		/*
418 		 * If this is a listening socket, disconnect the connecting or
419 		 * connected end.  If a connected peer was already created for
420 		 * the queued socket, dispose of that peer.
421 		 *
422 		 * Clear credentials obtained when starting to connect (in
423 		 * which case the socket is always a connection-oriented
424 		 * socket), so that they will not be mistaken for credentials
425 		 * obtained at bind time.
426 		 */
427 		if (uds_get_type(link) != SOCK_DGRAM) {
428 			if (uds_is_connected(link))
429 				uds_disconnect(link, TRUE /*was_linked*/);
430 			else
431 				uds_clear_cred(link);
432 		}
433 	}
434 
435 	assert(uds->uds_queued == found);
436 }
437 
438 /*
439  * Check whether the socket address given in 'addr', with length 'addr_len', is
440  * a valid UNIX domain socket address (including a path to a socket file).  On
441  * success, return the (non-zero) length of the socket file's path, minus the
442  * null terminator which may in fact not be present.  The caller is responsible
443  * for copying and terminating the path as needed.  A pointer to the path as
444  * stored in 'addr' is returned in 'pathp'.  On failure, return an error code.
445  */
446 static int
447 uds_check_addr(const struct sockaddr * addr, socklen_t addr_len,
448 	const char ** pathp)
449 {
450 	const char *p;
451 	size_t len;
452 
453 	/*
454 	 * We could cast to a sockaddr_un structure pointer first, but that
455 	 * would not provide any benefits here.  Instead, we use sa_data as the
456 	 * generic equivalent of sun_path.
457 	 */
458 	if (addr_len < offsetof(struct sockaddr, sa_data))
459 		return EINVAL;
460 
461 	if (addr->sa_family != AF_UNIX)
462 		return EAFNOSUPPORT;
463 
464 	len = (size_t)addr_len - offsetof(struct sockaddr, sa_data);
465 	if (len > 0 && (p = memchr(addr->sa_data, '\0', len)) != NULL)
466 		len = (size_t)(p - addr->sa_data);
467 
468 	/* The given path name must not be an empty string. */
469 	if (len == 0)
470 		return ENOENT;
471 
472 	/* This check should be redundant but better safe than sorry. */
473 	if (len >= UDS_PATH_MAX)
474 		return EINVAL;
475 
476 	*pathp = (const char *)addr->sa_data;
477 	return len;
478 }
479 
480 /*
481  * Given the socket file path given as 'path' with length 'path_len' (not
482  * necessarily null terminated), store a socket address with the path in
483  * 'addr', and return the socket address length in 'addr_len'.  The calling
484  * libraries (libsockdriver, libsockevent) and the static assert in uds.h
485  * guarantee that 'addr' is sufficiently large to store any address we generate
486  * here.  The libraries may subsequently copy out only a part of it to the user
487  * process.  This function always succeeds.
488  */
489 void
490 uds_make_addr(const char * path, size_t len, struct sockaddr * addr,
491 	socklen_t * addr_len)
492 {
493 
494 	/*
495 	 * Generate the address.  The stored length (sa_len/sun_len) does not
496 	 * include a null terminator.  The entire structure does include a null
497 	 * terminator, but only if the socket is bound.
498 	 */
499 	addr->sa_len = offsetof(struct sockaddr, sa_data) + len;
500 	addr->sa_family = AF_UNIX;
501 	if (len > 0) {
502 		/* This call may (intentionally) overrun the sa_data size. */
503 		memcpy((char *)addr->sa_data, path, len);
504 		((char *)addr->sa_data)[len] = '\0';
505 
506 		/* The socket is bound, so include the null terminator. */
507 		len++;
508 		assert(len <= UDS_PATH_MAX);
509 	}
510 
511 	/* Note that this length may be different from sa_len/sun_len now. */
512 	*addr_len = offsetof(struct sockaddr, sa_data) + len;
513 }
514 
515 /*
516  * Bind a socket to a local address.
517  */
518 static int
519 uds_bind(struct sock * sock, const struct sockaddr * addr, socklen_t addr_len,
520 	endpoint_t user_endpt)
521 {
522 	struct udssock *uds = (struct udssock *)sock;
523 	struct udssock *uds2;
524 	const char *path;
525 	size_t len;
526 	dev_t dev;
527 	ino_t ino;
528 	int r;
529 
530 	dprintf(("UDS: bind(%d)\n", uds_get_id(uds)));
531 
532 	/* A socket may be bound at any time, but only once. */
533 	if (uds_is_bound(uds))
534 		return EINVAL;
535 
536 	/* Verify that the user gave us an acceptable address. */
537 	if ((r = uds_check_addr(addr, addr_len, &path)) < 0)
538 		return r;
539 	len = (size_t)r;
540 
541 	/* Attempt to create the socket file on the file system. */
542 	r = socketpath(user_endpt, path, len, SPATH_CREATE, &dev, &ino);
543 	if (r != OK)
544 		return r;
545 	assert(dev != NO_DEV && ino != 0);
546 
547 	/*
548 	 * It is possible that a socket file of a previously bound socket was
549 	 * unlinked, and due to inode number reuse, a new socket file has now
550 	 * been created with the same <dev,ino> pair.  In that case, we must
551 	 * unbind the old socket, because it must no longer be found.  The old
552 	 * socket will still have a path (and behave as though it is bound) but
553 	 * no longer be found through hash lookups.
554 	 */
555 	if ((uds2 = udshash_get(dev, ino)) != NULL) {
556 		udshash_del(uds2);
557 
558 		uds2->uds_dev = NO_DEV;
559 		uds2->uds_ino = 0;
560 	}
561 
562 	/*
563 	 * Obtain credentials for the socket, unless the socket is already
564 	 * connecting or connected, in which case we must not replace the
565 	 * credentials we obtained already.  We later clear those credentials
566 	 * upon a connection failure or disconnect, so that if the socket is
567 	 * then put in listening mode, we know there are no bind-time
568 	 * credentials.  Not ideal, but we really need two separate sets of
569 	 * credentials if we want to get this right, which is a waste of memory
570 	 * as no sane application writer would ever rely on credential passing
571 	 * after recycling a socket..
572 	 */
573 	if (uds_get_type(uds) != SOCK_DGRAM && !uds_is_connecting(uds) &&
574 	    !uds_is_connected(uds))
575 		uds_get_cred(uds, user_endpt);
576 
577 	/* Asssign the address to the socket. */
578 	uds->uds_pathlen = len;
579 	memcpy(&uds->uds_path, path, len);
580 	uds->uds_dev = dev;
581 	uds->uds_ino = ino;
582 
583 	udshash_add(uds);
584 
585 	return OK;
586 }
587 
588 /*
589  * Look up a UDS socket based on a user-given address.  If a socket exists for
590  * the address, check if it is type-compatible with the given UDS socket.
591  * On succes, return OK, with 'peerp' set to the socket that was found.  On
592  * failure, return a negative error code.
593  */
594 int
595 uds_lookup(struct udssock * uds, const struct sockaddr * addr,
596 	socklen_t addr_len, endpoint_t user_endpt, struct udssock ** peerp)
597 {
598 	struct udssock *peer;
599 	const char *path;
600 	size_t len;
601 	dev_t dev;
602 	ino_t ino;
603 	int r;
604 
605 	/* Verify that the user gave us an acceptable address. */
606 	if ((r = uds_check_addr(addr, addr_len, &path)) < 0)
607 		return r;
608 	len = (size_t)r;
609 
610 	/* Attempt to look up the socket file on the file system. */
611 	r = socketpath(user_endpt, path, len, SPATH_CHECK, &dev, &ino);
612 	if (r != OK)
613 		return r;
614 	assert(dev != NO_DEV && ino != 0);
615 
616 	if ((peer = udshash_get(dev, ino)) == NULL)
617 		return ECONNREFUSED;
618 	if (uds_get_type(peer) != uds_get_type(uds))
619 		return EPROTOTYPE;
620 
621 	*peerp = peer;
622 	return OK;
623 }
624 
625 /*
626  * Given the listening socket 'uds', and the socket 'link' that is calling or
627  * has called connect(2) and is or will be linked to the listening socket's
628  * queue, create a new socket and connect it to 'link', putting both sockets in
629  * the connected state.  The given link socket may be in unconnected,
630  * connecting, or disconnected state prior to the call.  Return OK or an error
631  * code.  The link state of the link socket remains unchanged in any case.
632  */
633 static int
634 uds_attach(struct udssock * uds, struct udssock * link)
635 {
636 	struct udssock *conn;
637 	int r;
638 
639 	/*
640 	 * Allocate a new socket to use as peer socket for the connection that
641 	 * is about to be established.  The new socket is not yet known by
642 	 * libsockevent.
643 	 */
644 	if ((r = uds_alloc(&conn)) != OK)
645 		return r;
646 
647 	/*
648 	 * Ask libsockevent to clone the sock object in the new UDS socket from
649 	 * the listening socket.  This adds the sock object to libsockevent's
650 	 * data structures and ensures that we can safely use the socket
651 	 * despite the fact that it has not yet been accepted (and thus
652 	 * returned to libsockevent).  From this moment on, we must either
653 	 * return the socket's ID (but not a pointer to it!) from uds_accept()
654 	 * or raise SEV_CLOSE on it.
655 	 */
656 	sockevent_clone(&uds->uds_sock, &conn->uds_sock, uds_get_id(conn));
657 
658 	/* Connect the link socket to the new socket. */
659 	link->uds_conn = conn;
660 	link->uds_flags |= UDSF_CONNECTED;
661 
662 	/*
663 	 * Connect the new socket to the link socket as well.  The child
664 	 * socket should also inherit pretty much all settings from the
665 	 * listening socket, including the bind path and the listening socket's
666 	 * bind-time credentials.
667 	 */
668 	conn->uds_conn = link;
669 	conn->uds_flags = uds->uds_flags & (UDSF_PASSCRED | UDSF_CONNWAIT);
670 	conn->uds_flags |= UDSF_CONNECTED;
671 	conn->uds_pathlen = uds->uds_pathlen;
672 	memcpy(conn->uds_path, uds->uds_path, (size_t)uds->uds_pathlen);
673 	memcpy(&conn->uds_cred, &uds->uds_cred, sizeof(conn->uds_cred));
674 
675 	return OK;
676 }
677 
678 /*
679  * Connect a socket to a remote address.
680  */
681 static int
682 uds_connect(struct sock * sock, const struct sockaddr * addr,
683 	socklen_t addr_len, endpoint_t user_endpt)
684 {
685 	struct udssock *uds = (struct udssock *)sock;
686 	struct udssock *link;
687 	int r;
688 
689 	dprintf(("UDS: connect(%d)\n", uds_get_id(uds)));
690 
691 	/* For connection-oriented sockets, several state checks apply. */
692 	if (uds_get_type(uds) != SOCK_DGRAM) {
693 		if (uds_is_listening(uds))
694 			return EOPNOTSUPP;
695 		if (uds_is_connecting(uds))
696 			return EALREADY;
697 		if (uds_is_connected(uds))
698 			return EISCONN;
699 		/* Disconnected sockets may be reconnected, see below. */
700 	} else {
701 		/*
702 		 * Connectionless sockets may be unconnected by providing an
703 		 * address with family AF_UNSPEC.  Handle this case first here.
704 		 */
705 		if (addr_len >= offsetof(struct sockaddr, sa_data) &&
706 		    addr->sa_family == AF_UNSPEC) {
707 			/*
708 			 * Reset this socket's previous connection to another
709 			 * socket, if any.  Unconnecting has no effect on other
710 			 * sockets connected to this socket, though.
711 			 */
712 			if (uds_has_link(uds))
713 				uds_del_queue(uds->uds_link, uds);
714 
715 			return OK;
716 		}
717 	}
718 
719 	/*
720 	 * Find the socket identified by the given address.  If it exists at
721 	 * all, see if it is a proper match.
722 	 */
723 	if ((r = uds_lookup(uds, addr, addr_len, user_endpt, &link)) != OK)
724 		return r;
725 
726 	/*
727 	 * Handle connectionless sockets first, in which case a connect links
728 	 * the socket to a send target and limits receipt to datagrams from
729 	 * that target.  We actually point the socket to the peer socket,
730 	 * through uds_link.  That also means that if the target socket
731 	 * disappears, we have to reset any sockets connected to it, in which
732 	 * case we return them to the unconnected state.  In order to allow
733 	 * finding all sockets connected to a particular socket, we put all
734 	 * those sockets on their target's queue, hence why we use uds_link and
735 	 * not uds_conn.  As mentioned before, we allow reconnecting without
736 	 * restrictions.
737 	 * TODO: see if reconnecting should clear a pending ECONNRESET.
738 	 *
739 	 * An important note: 'uds' and 'link' may actually be the same socket,
740 	 * if the caller chooses to connect a socket with itself!
741 	 */
742 	if (uds_get_type(uds) == SOCK_DGRAM) {
743 		/* Reconnecting to the same socket has no effect. */
744 		if (uds_has_link(uds) && uds->uds_link == link)
745 			return OK;
746 
747 		/*
748 		 * If the intended target is linked to another socket, we
749 		 * refuse linking to it.  Sending or receiving would never work
750 		 * anyway.  Do allow a socket to link to itself after being
751 		 * linked to another socket.  The error code is the same as in
752 		 * the sending code, borrowed from Linux.
753 		 */
754 		if (uds != link && uds_has_link(link) && link->uds_link != uds)
755 			return EPERM;
756 
757 		/*
758 		 * Reset this socket's previous link to another socket, if any.
759 		 */
760 		if (uds_has_link(uds))
761 			uds_del_queue(uds->uds_link, uds);
762 
763 		/*
764 		 * Reset any links to this socket, except for the one by
765 		 * the intended target.  Sending or receiving would no longer
766 		 * work anyway.  If the socket was linked to itself, clear its
767 		 * self-link without generating an ECONNRESET.  If the socket
768 		 * is relinking to itself, reestablish the link after first
769 		 * clearing it.
770 		 */
771 		uds_clear_queue(uds, (uds != link) ? link : NULL);
772 
773 		uds_add_queue(link, uds);
774 
775 		return OK;
776 	}
777 
778 	/*
779 	 * For connection-oriented sockets there is more to do.  First, make
780 	 * sure that the peer is a listening socket, that it has not been shut
781 	 * down, and that its backlog is not already at the configured maximum.
782 	 */
783 	if (!uds_is_listening(link))
784 		return ECONNREFUSED;
785 
786 	if (uds_is_shutdown(link, SFL_SHUT_RD | SFL_SHUT_WR))
787 		return ECONNREFUSED;
788 
789 	if (link->uds_queued >= link->uds_backlog)
790 		return ECONNREFUSED;
791 
792 	/*
793 	 * The behavior of connect(2) now depends on whether LOCAL_CONNWAIT is
794 	 * set on either the connecting or the listening socket.  If it is not,
795 	 * the socket will be connected to a new as-yet invisible socket, which
796 	 * will be the one returned from accept(2) later.  If it was, the
797 	 * socket will be put in the connecting state.
798 	 */
799 	if (!((uds->uds_flags | link->uds_flags) & UDSF_CONNWAIT)) {
800 		if ((r = uds_attach(link, uds)) != OK)
801 			return r;
802 
803 		assert(uds_is_connected(uds));
804 	} else {
805 		/*
806 		 * Disconnected sockets now stop being connected.  Any pending
807 		 * data can still be received, though.
808 		 */
809 		uds->uds_flags &= ~UDSF_CONNECTED;
810 
811 		r = SUSPEND;
812 	}
813 
814 	/* Obtain credentials for the socket. */
815 	uds_get_cred(uds, user_endpt);
816 
817 	/* Add the socket at the end of the listening socket's queue. */
818 	uds_add_queue(link, uds);
819 
820 	assert(r != SUSPEND || uds_is_connecting(uds));
821 
822 	/*
823 	 * Let an accept call handle the rest, which will in turn resume this
824 	 * connect call.  The sockevent library ensures that this works even if
825 	 * the call is non-blocking.
826 	 */
827 	sockevent_raise(&link->uds_sock, SEV_ACCEPT);
828 
829 	return r;
830 }
831 
832 /*
833  * Put a socket in listening mode.
834  */
835 static int
836 uds_listen(struct sock * sock, int backlog)
837 {
838 	struct udssock *uds = (struct udssock *)sock;
839 
840 	/* The maximum backlog value must not exceed its field size. */
841 	assert(SOMAXCONN <= USHRT_MAX);
842 
843 	dprintf(("UDS: listen(%d)\n", uds_get_id(uds)));
844 
845 	/* Only connection-oriented types may be put in listening mode. */
846 	if (uds_get_type(uds) == SOCK_DGRAM)
847 		return EOPNOTSUPP;
848 
849 	/* A connecting or connected socket may not listen. */
850 	if (uds_is_connecting(uds) || uds_is_connected(uds))
851 		return EINVAL;
852 
853 	/* POSIX says that this is now the appropriate error code here. */
854 	if (!uds_is_bound(uds))
855 		return EDESTADDRREQ;
856 
857 	/*
858 	 * The socket is now entering the listening state.  If it was
859 	 * previously disconnected, clear the connection flag.
860 	 */
861 	uds->uds_flags &= ~UDSF_CONNECTED;
862 
863 	/*
864 	 * We do not remove sockets from the backlog if it is now being dropped
865 	 * below the current number of queued sockets.  We only refuse newly
866 	 * connecting sockets beyond the backlog size.
867 	 */
868 	uds->uds_backlog = backlog;
869 
870 	return OK;
871 }
872 
873 /*
874  * Test whether an accept request would block.  Return OK if a socket could be
875  * accepted, an appropriate error code if an accept call would fail instantly,
876  * or SUSPEND if the accept request would block waiting for a connection.
877  */
878 static int
879 uds_test_accept(struct sock * sock)
880 {
881 	struct udssock *uds = (struct udssock *)sock;
882 
883 	/*
884 	 * Ensure that the socket is in listening mode.  If not, we must return
885 	 * the error code that is appropriate for this socket type.
886 	 */
887 	if (uds_get_type(uds) == SOCK_DGRAM)
888 		return EOPNOTSUPP;
889 	if (!uds_is_listening(uds))
890 		return EINVAL;
891 
892 	/*
893 	 * If the socket has been shut down, new connections are no longer
894 	 * accepted and accept calls no longer block.  This is not a POSIX
895 	 * requirement, but rather an application convenience feature.
896 	 */
897 	if (uds->uds_queued == 0) {
898 		if (uds_is_shutdown(uds, SFL_SHUT_RD | SFL_SHUT_WR))
899 			return ECONNABORTED;
900 
901 		return SUSPEND;
902 	}
903 
904 	return OK;
905 }
906 
907 /*
908  * Accept a connection on a listening socket, creating a new socket.  On
909  * success, return the new socket identifier, with the new socket stored in
910  * 'newsockp'.  Otherwise, return an error code.
911  */
912 static sockid_t
913 uds_accept(struct sock * sock, struct sockaddr * addr, socklen_t * addr_len,
914 	endpoint_t user_endpt __unused, struct sock ** newsockp)
915 {
916 	struct udssock *uds = (struct udssock *)sock;
917 	struct udssock *link, *conn;
918 	sockid_t r;
919 
920 	dprintf(("UDS: accept(%d)\n", uds_get_id(uds)));
921 
922 	if ((r = uds_test_accept(sock)) != OK)
923 		return r;
924 
925 	/*
926 	 * Take the first connecting socket off the listening queue.
927 	 */
928 	assert(!TAILQ_EMPTY(&uds->uds_queue));
929 
930 	link = TAILQ_FIRST(&uds->uds_queue);
931 
932 	/*
933 	 * Depending on the LOCAL_CONNWAIT setting at the time of connect(2),
934 	 * the socket may be connecting or connected.  In the latter case, its
935 	 * attached socket is the socket we will return now.  Otherwise we have
936 	 * to attach a socket first.
937 	 */
938 	assert(uds_is_connecting(link) || uds_is_connected(link));
939 
940 	if (uds_is_connecting(link)) {
941 		/*
942 		 * Attach a new socket.  If this fails, return the error but
943 		 * leave the connecting socket on the listening queue.
944 		 */
945 		if ((r = uds_attach(uds, link)) != OK)
946 			return r;
947 
948 		assert(uds_is_connected(link));
949 
950 		/*
951 		 * Wake up blocked (connect, send, select) calls on the peer
952 		 * socket.
953 		 */
954 		sockevent_raise(&link->uds_sock, SEV_CONNECT);
955 	}
956 
957 	uds_del_queue(uds, link);
958 
959 	/* Return the peer socket's address to the caller. */
960 	uds_make_addr(link->uds_path, link->uds_pathlen, addr, addr_len);
961 
962 	conn = link->uds_conn;
963 
964 	dprintf(("UDS: accept returns %d\n", uds_get_id(conn)));
965 
966 	/*
967 	 * We already cloned the sock object, so return its ID but not a
968 	 * pointer to it.  That tells libsockevent not to reinitialize it.
969 	 */
970 	*newsockp = NULL;
971 	return uds_get_id(conn);
972 }
973 
974 /*
975  * Set socket options.
976  */
977 static int
978 uds_setsockopt(struct sock * sock, int level, int name,
979 	const struct sockdriver_data * data, socklen_t len)
980 {
981 	struct udssock *uds = (struct udssock *)sock;
982 	int r, val;
983 
984 	dprintf(("UDS: setsockopt(%d,%d,%d)\n", uds_get_id(uds), level, name));
985 
986 	switch (level) {
987 	case SOL_SOCKET:
988 		switch (name) {
989 		case SO_SNDBUF:
990 		case SO_RCVBUF:
991 			/*
992 			 * The send buffer size may not be changed because the
993 			 * buffer is the same as the other side's receive
994 			 * buffer, and what the other side is may vary from
995 			 * send call to send call.  Changing the receive buffer
996 			 * size would disallow us from even accurately guessing
997 			 * the send buffer size in getsockopt calls.  Therefore
998 			 * both are hardcoded and cannot actually be changed.
999 			 * In order to support applications that want at least
1000 			 * a certain minimum, we do accept requests to shrink
1001 			 * either buffer, but we ignore the given size.
1002 			 */
1003 			if ((r = sockdriver_copyin_opt(data, &val, sizeof(val),
1004 			    len)) != OK)
1005 				return r;
1006 
1007 			if (val <= 0 || (size_t)val > uds_io_buflen())
1008 				return EINVAL;
1009 
1010 			return OK; /* ignore new value */
1011 		}
1012 
1013 		break;
1014 
1015 	case UDSPROTO_UDS:
1016 		switch (name) {
1017 		case LOCAL_CREDS:
1018 			if ((r = sockdriver_copyin_opt(data, &val, sizeof(val),
1019 			    len)) != OK)
1020 				return r;
1021 
1022 			if (val)
1023 				uds->uds_flags |= UDSF_PASSCRED;
1024 			else
1025 				uds->uds_flags &= ~UDSF_PASSCRED;
1026 
1027 			/*
1028 			 * In incredibly rare cases, disabling this flag may
1029 			 * allow blocked sends to be resumed, because suddenly
1030 			 * no room for the credentials is needed in the receive
1031 			 * buffer anymore.
1032 			 */
1033 			if (!val)
1034 				sockevent_raise(&uds->uds_sock, SEV_SEND);
1035 
1036 			return OK;
1037 
1038 		case LOCAL_CONNWAIT:
1039 			if ((r = sockdriver_copyin_opt(data, &val, sizeof(val),
1040 			    len)) != OK)
1041 				return r;
1042 
1043 			if (val)
1044 				uds->uds_flags |= UDSF_CONNWAIT;
1045 			else
1046 				uds->uds_flags &= ~UDSF_CONNWAIT;
1047 
1048 			/*
1049 			 * Changing the setting does not affect sockets that
1050 			 * are currently pending to be accepted.  Therefore,
1051 			 * uds_accept() may have to deal with either case on a
1052 			 * socket-by-socket basis.
1053 			 */
1054 			return OK;
1055 
1056 		case LOCAL_PEEREID:
1057 			/* This option may be retrieved but not set. */
1058 			return ENOPROTOOPT;
1059 		}
1060 
1061 		break;
1062 	}
1063 
1064 	return ENOPROTOOPT;
1065 }
1066 
1067 /*
1068  * Retrieve socket options.
1069  */
1070 static int
1071 uds_getsockopt(struct sock * sock, int level, int name,
1072 	const struct sockdriver_data * data, socklen_t * len)
1073 {
1074 	struct udssock *uds = (struct udssock *)sock;
1075 	int val;
1076 
1077 	dprintf(("UDS: getsockopt(%d,%d,%d)\n", uds_get_id(uds), level, name));
1078 
1079 	switch (level) {
1080 	case SOL_SOCKET:
1081 		switch (name) {
1082 		case SO_SNDBUF:
1083 		case SO_RCVBUF:
1084 			/* See uds_setsockopt() for why this is static. */
1085 			val = (int)uds_io_buflen();
1086 
1087 			return sockdriver_copyout_opt(data, &val, sizeof(val),
1088 			    len);
1089 		}
1090 
1091 		break;
1092 
1093 	case UDSPROTO_UDS:
1094 		switch (name) {
1095 		case LOCAL_CREDS:
1096 			val = !!(uds->uds_flags & UDSF_PASSCRED);
1097 
1098 			return sockdriver_copyout_opt(data, &val, sizeof(val),
1099 			    len);
1100 
1101 		case LOCAL_CONNWAIT:
1102 			val = !!(uds->uds_flags & UDSF_CONNWAIT);
1103 
1104 			return sockdriver_copyout_opt(data, &val, sizeof(val),
1105 			    len);
1106 
1107 		case LOCAL_PEEREID:
1108 			/* getpeereid(3) documents these error codes. */
1109 			if (uds_get_type(uds) == SOCK_DGRAM)
1110 				return EINVAL;
1111 			if (!uds_is_connected(uds))
1112 				return ENOTCONN;
1113 
1114 			/*
1115 			 * This is a custom MINIX3 error, indicating that there
1116 			 * are no credentials to return.  This could be due to
1117 			 * a failure to obtain them (which *should* not happen)
1118 			 * but also if the socket was bound while connected,
1119 			 * disconnected, and then reused as listening socket.
1120 			 */
1121 			if (uds->uds_conn->uds_cred.unp_pid == -1)
1122 				return EINVAL;
1123 
1124 			return sockdriver_copyout_opt(data,
1125 			    &uds->uds_conn->uds_cred,
1126 			    sizeof(uds->uds_conn->uds_cred), len);
1127 		}
1128 
1129 		break;
1130 	}
1131 
1132 	return ENOPROTOOPT;
1133 }
1134 
1135 /*
1136  * Retrieve a socket's local address.
1137  */
1138 static int
1139 uds_getsockname(struct sock * sock, struct sockaddr * addr,
1140 	socklen_t * addr_len)
1141 {
1142 	struct udssock *uds = (struct udssock *)sock;
1143 
1144 	dprintf(("UDS: getsockname(%d)\n", uds_get_id(uds)));
1145 
1146 	uds_make_addr(uds->uds_path, uds->uds_pathlen, addr, addr_len);
1147 
1148 	return OK;
1149 }
1150 
1151 /*
1152  * Retrieve a socket's remote address.
1153  */
1154 static int
1155 uds_getpeername(struct sock * sock, struct sockaddr * addr,
1156 	socklen_t * addr_len)
1157 {
1158 	struct udssock *uds = (struct udssock *)sock;
1159 	struct udssock *peer;
1160 
1161 	dprintf(("UDS: getpeername(%d)\n", uds_get_id(uds)));
1162 
1163 	/*
1164 	 * For disconnected sockets, we no longer have a peer socket and thus
1165 	 * also no peer address.  Too bad, but NetBSD does the same.
1166 	 *
1167 	 * For connecting sockets we could in fact return a peer address, but
1168 	 * POSIX says (and other platforms agree) that we should deny the call.
1169 	 */
1170 	peer = uds_get_peer(uds);
1171 
1172 	if (peer == NULL || uds_is_connecting(uds))
1173 		return ENOTCONN;
1174 
1175 	uds_make_addr(peer->uds_path, peer->uds_pathlen, addr, addr_len);
1176 
1177 	return OK;
1178 }
1179 
1180 /*
1181  * Shut down socket send and receive operations.  Note that 'flags' is a
1182  * bitwise mask with libsockevent's SFL_SHUT_{RD,WR} flags rather than the set
1183  * of SHUT_{RD,WR,RDWR} values from userland.
1184  */
1185 static int
1186 uds_shutdown(struct sock * sock, unsigned int flags)
1187 {
1188 	struct udssock *uds = (struct udssock *)sock;
1189 	struct udssock *conn;
1190 	unsigned int mask;
1191 
1192 	dprintf(("UDS: shutdown(%d,0x%x)\n", uds_get_id(uds), flags));
1193 
1194 	/*
1195 	 * If we are shutting down the socket for reading, we can already close
1196 	 * any in-flight file descriptors associated with this socket.
1197 	 */
1198 	if (flags & SFL_SHUT_RD)
1199 		uds_io_reset(uds);
1200 
1201 	/*
1202 	 * A shutdown on this side of a connection may have an effect on
1203 	 * ongoing operations on the other side.  Fire appropriate events.
1204 	 */
1205 	if (uds_is_connected(uds)) {
1206 		assert(uds_get_type(uds) != SOCK_DGRAM);
1207 
1208 		conn = uds->uds_conn;
1209 
1210 		mask = 0;
1211 		if (flags & SFL_SHUT_RD)
1212 			mask |= SEV_SEND;
1213 		if (flags & SFL_SHUT_WR)
1214 			mask |= SEV_RECV;
1215 
1216 		sockevent_raise(&conn->uds_sock, mask);
1217 	}
1218 
1219 	return OK;
1220 }
1221 
1222 /*
1223  * Close a socket.
1224  *
1225  * The 'force' flag is unused because we need never wait for data to be sent,
1226  * since we keep all in-flight data on the receiver side.
1227  */
1228 static int
1229 uds_close(struct sock * sock, int force __unused)
1230 {
1231 	struct udssock *uds = (struct udssock *)sock;
1232 
1233 	dprintf(("UDS: close(%d)\n", uds_get_id(uds)));
1234 
1235 	if (uds_get_type(uds) == SOCK_DGRAM) {
1236 		/* If this socket is linked to a target, disconnect it. */
1237 		if (uds_has_link(uds))
1238 			uds_del_queue(uds->uds_link, uds);
1239 
1240 		/* Reset all sockets linked to this socket as a target. */
1241 		uds_clear_queue(uds, NULL);
1242 	} else if (uds_is_listening(uds)) {
1243 		/*
1244 		 * Abort all connecting sockets queued on this socket, and
1245 		 * break all connections for connected sockets queued on this
1246 		 * socket, freeing their peers.
1247 		 */
1248 		uds_clear_queue(uds, NULL);
1249 	} else if (uds_has_link(uds)) {
1250 		/*
1251 		 * This socket is connecting or connected while the other side
1252 		 * has not been accepted yet.  Remove the socket from the
1253 		 * listening socket's queue, and if it was connected, get rid
1254 		 * of its peer socket altogether.
1255 		 */
1256 		assert(uds_is_listening(uds->uds_link));
1257 
1258 		uds_del_queue(uds->uds_link, uds);
1259 
1260 		if (uds_is_connected(uds))
1261 			uds_disconnect(uds, TRUE /*was_linked*/);
1262 	} else if (uds_is_connected(uds)) {
1263 		/*
1264 		 * Decouple the peer socket from this socket, and possibly wake
1265 		 * up any pending operations on it.  The socket remains marked
1266 		 * as connected, but will now be disconnected.
1267 		 */
1268 		uds_disconnect(uds, FALSE /*was_linked*/);
1269 	}
1270 
1271 	if (uds_is_hashed(uds))
1272 		udshash_del(uds);
1273 
1274 	return OK;
1275 }
1276 
1277 static const struct sockevent_ops uds_ops = {
1278 	.sop_pair		= uds_pair,
1279 	.sop_bind		= uds_bind,
1280 	.sop_connect		= uds_connect,
1281 	.sop_listen		= uds_listen,
1282 	.sop_accept		= uds_accept,
1283 	.sop_test_accept	= uds_test_accept,
1284 	.sop_pre_send		= uds_pre_send,
1285 	.sop_send		= uds_send,
1286 	.sop_test_send		= uds_test_send,
1287 	.sop_pre_recv		= uds_pre_recv,
1288 	.sop_recv		= uds_recv,
1289 	.sop_test_recv		= uds_test_recv,
1290 	.sop_setsockopt		= uds_setsockopt,
1291 	.sop_getsockopt		= uds_getsockopt,
1292 	.sop_getsockname	= uds_getsockname,
1293 	.sop_getpeername	= uds_getpeername,
1294 	.sop_shutdown		= uds_shutdown,
1295 	.sop_close		= uds_close,
1296 	.sop_free		= uds_free
1297 };
1298 
1299 /*
1300  * Initialize the service.
1301  */
1302 static int
1303 uds_init(int type __unused, sef_init_info_t * info __unused)
1304 {
1305 	unsigned int i;
1306 
1307 	/* Initialize the list of free sockets. */
1308 	TAILQ_INIT(&uds_freelist);
1309 
1310 	for (i = 0; i < __arraycount(uds_array); i++) {
1311 		uds_array[i].uds_flags = 0;
1312 
1313 		TAILQ_INSERT_TAIL(&uds_freelist, &uds_array[i], uds_next);
1314 	}
1315 
1316 	/* Initialize the file-to-socket hash table. */
1317 	udshash_init();
1318 
1319 	/* Initialize the input/output module. */
1320 	uds_io_init();
1321 
1322 	/* Initialize the status module. */
1323 	uds_stat_init();
1324 
1325 	/* Initialize the sockevent library. */
1326 	sockevent_init(uds_socket);
1327 
1328 	uds_in_use = 0;
1329 	uds_running = TRUE;
1330 
1331 	return OK;
1332 }
1333 
1334 /*
1335  * Clean up before shutdown.
1336  */
1337 static void
1338 uds_cleanup(void)
1339 {
1340 
1341 	/* Tell the status module to clean up. */
1342 	uds_stat_cleanup();
1343 }
1344 
1345 /*
1346  * The service has received a signal.
1347  */
1348 static void
1349 uds_signal(int signo)
1350 {
1351 
1352 	/* Only check for the termination signal.  Ignore anything else. */
1353 	if (signo != SIGTERM)
1354 		return;
1355 
1356 	/* Exit only once all sockets have been closed. */
1357 	uds_running = FALSE;
1358 
1359 	if (uds_in_use == 0)
1360 		sef_cancel();
1361 }
1362 
1363 /*
1364  * Perform initialization using the System Event Framework (SEF).
1365  */
1366 static void
1367 uds_startup(void)
1368 {
1369 
1370 	/* Register initialization callbacks. */
1371 	sef_setcb_init_fresh(uds_init);
1372 
1373 	/* Register signal callback. */
1374 	sef_setcb_signal_handler(uds_signal);
1375 
1376 	/* Let SEF perform startup. */
1377 	sef_startup();
1378 }
1379 
1380 /*
1381  * The UNIX Domain Sockets driver.
1382  */
1383 int
1384 main(void)
1385 {
1386 	message m;
1387 	int r, ipc_status;
1388 
1389 	/* Initialize the service. */
1390 	uds_startup();
1391 
1392 	/* Loop receiving and processing messages until instructed to stop. */
1393 	while (uds_running || uds_in_use > 0) {
1394 		if ((r = sef_receive_status(ANY, &m, &ipc_status)) != OK) {
1395 			if (r == EINTR)
1396 				continue;	/* sef_cancel() was called */
1397 
1398 			panic("UDS: sef_receive_status failed: %d", r);
1399 		}
1400 
1401 		/*
1402 		 * Messages from the MIB service are (ultimately) for the
1403 		 * status module.  Everything else is assumed to be a socket
1404 		 * request and passed to libsockevent, which will ignore
1405 		 * anything it does not recognize.
1406 		 */
1407 		if (m.m_source == MIB_PROC_NR)
1408 			rmib_process(&m, ipc_status);
1409 		else
1410 			sockevent_process(&m, ipc_status);
1411 	}
1412 
1413 	/* Clean up before graceful shutdown. */
1414 	uds_cleanup();
1415 
1416 	return EXIT_SUCCESS;
1417 }
1418