xref: /haiku/src/system/kernel/fs/socket.cpp (revision e9c4d47ad719d6fd67cd9b75b41ebbec563e7a79)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <sys/socket.h>
7 
8 #include <errno.h>
9 #include <limits.h>
10 
11 #include <module.h>
12 
13 #include <AutoDeleter.h>
14 
15 #include <syscall_utils.h>
16 
17 #include <fd.h>
18 #include <kernel.h>
19 #include <syscall_restart.h>
20 #include <vfs.h>
21 
22 #include <net_stack_interface.h>
23 #include <net_stat.h>
24 
25 
26 #define MAX_SOCKET_ADDRESS_LEN	(sizeof(sockaddr_storage))
27 #define MAX_SOCKET_OPTION_LEN	128
28 #define MAX_ANCILLARY_DATA_LEN	1024
29 
30 
31 static net_stack_interface_module_info* sStackInterface = NULL;
32 static vint32 sStackInterfaceInitialized = 0;
33 
34 
35 struct FDPutter {
36 	FDPutter(file_descriptor* descriptor)
37 		: descriptor(descriptor)
38 	{
39 	}
40 
41 	~FDPutter()
42 	{
43 		if (descriptor != NULL)
44 			put_fd(descriptor);
45 	}
46 
47 
48 	file_descriptor*	descriptor;
49 };
50 
51 
52 static net_stack_interface_module_info*
53 init_stack_interface_module()
54 {
55 	// TODO: Add driver settings option to load the userland net stack.
56 
57 	// load module
58 	net_stack_interface_module_info* module;
59 	status_t error = get_module(NET_STACK_INTERFACE_MODULE_NAME,
60 		(module_info**)&module);
61 	if (error != B_OK)
62 		return NULL;
63 
64 	sStackInterface = module;	// assumed to be atomic
65 
66 	// If someone else was faster getting the module, we put our reference.
67 	if (atomic_test_and_set(&sStackInterfaceInitialized, 1, 0) != 0)
68 		put_module(module->info.name);
69 
70 	return module;
71 }
72 
73 
74 static inline net_stack_interface_module_info*
75 get_stack_interface_module()
76 {
77 	if (sStackInterface)
78 		return sStackInterface;
79 
80 	return init_stack_interface_module();
81 }
82 
83 
84 static status_t
85 prepare_userland_address_result(struct sockaddr* userAddress,
86 	socklen_t* _addressLength, socklen_t& addressLength, bool addressRequired)
87 {
88 	// check parameters
89 	if (_addressLength == NULL)
90 		return B_BAD_VALUE;
91 	if (userAddress == NULL) {
92 		if (addressRequired)
93 			return B_BAD_VALUE;
94 	} else if (!IS_USER_ADDRESS(userAddress)
95 			|| !IS_USER_ADDRESS(_addressLength)) {
96 		return B_BAD_ADDRESS;
97 	}
98 
99 	// copy the buffer size from userland
100 	addressLength = 0;
101 	if (userAddress != NULL
102 			&& user_memcpy(&addressLength, _addressLength, sizeof(socklen_t))
103 				!= B_OK) {
104 		return B_BAD_ADDRESS;
105 	}
106 
107 	if (addressLength > MAX_SOCKET_ADDRESS_LEN)
108 		addressLength = MAX_SOCKET_ADDRESS_LEN;
109 
110 	return B_OK;
111 }
112 
113 
114 static status_t
115 copy_address_to_userland(const void* address, socklen_t addressLength,
116 	sockaddr* userAddress, socklen_t userAddressBufferSize,
117 	socklen_t* userAddressLength)
118 {
119 	// copy address size and address back to userland
120 	if (user_memcpy(userAddressLength, &addressLength,
121 			sizeof(socklen_t)) != B_OK
122 		|| userAddress != NULL
123 			&& user_memcpy(userAddress, address,
124 				min_c(addressLength, userAddressBufferSize)) != B_OK) {
125 		return B_BAD_ADDRESS;
126 	}
127 
128 	return B_OK;
129 }
130 
131 
132 static status_t
133 prepare_userland_msghdr(const msghdr* userMessage, msghdr& message,
134 	iovec*& userVecs, MemoryDeleter& vecsDeleter, void*& userAddress,
135 	char* address)
136 {
137 	if (userMessage == NULL)
138 		return B_BAD_VALUE;
139 
140 	// copy message from userland
141 	if (!IS_USER_ADDRESS(userMessage)
142 			|| user_memcpy(&message, userMessage, sizeof(msghdr)) != B_OK) {
143 		return B_BAD_ADDRESS;
144 	}
145 
146 	userVecs = message.msg_iov;
147 	userAddress = message.msg_name;
148 
149 	// copy iovecs from userland
150 	if (message.msg_iovlen < 0 || message.msg_iovlen > IOV_MAX)
151 		return EMSGSIZE;
152 	if (userVecs != NULL && message.msg_iovlen > 0) {
153 		iovec* vecs = (iovec*)malloc(sizeof(iovec) * message.msg_iovlen);
154 		if (vecs == NULL)
155 			return B_NO_MEMORY;
156 		vecsDeleter.SetTo(vecs);
157 
158 		if (!IS_USER_ADDRESS(message.msg_iov)
159 				|| user_memcpy(vecs, message.msg_iov,
160 					message.msg_iovlen * sizeof(iovec)) != B_OK) {
161 			return B_BAD_ADDRESS;
162 		}
163 
164 		for (int i = 0; i < message.msg_iovlen; i++) {
165 			if (!IS_USER_ADDRESS(vecs[i].iov_base))
166 				return B_BAD_ADDRESS;
167 		}
168 
169 		message.msg_iov = vecs;
170 	} else {
171 		message.msg_iov = NULL;
172 		message.msg_iovlen = 0;
173 	}
174 
175 	// prepare the address field
176 	userAddress = message.msg_name;
177 	if (userAddress != NULL) {
178 		if (!IS_USER_ADDRESS(message.msg_name))
179 			return B_BAD_ADDRESS;
180 		if (message.msg_namelen > MAX_SOCKET_ADDRESS_LEN)
181 			message.msg_namelen = MAX_SOCKET_ADDRESS_LEN;
182 
183 		message.msg_name = address;
184 	}
185 
186 	return B_OK;
187 }
188 
189 
190 static status_t
191 get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor)
192 {
193 	if (fd < 0)
194 		return EBADF;
195 
196 	descriptor = get_fd(get_current_io_context(kernel), fd);
197 	if (descriptor == NULL)
198 		return EBADF;
199 
200 	if (descriptor->type != FDTYPE_SOCKET) {
201 		put_fd(descriptor);
202 		return ENOTSOCK;
203 	}
204 
205 	return B_OK;
206 }
207 
208 
209 #define GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor)	\
210 	do {												\
211 		status_t gsfdorError = get_socket_descriptor(fd, kernel, descriptor); \
212 		if (gsfdorError != B_OK)						\
213 			return gsfdorError;							\
214 	} while (false)
215 
216 
217 // #pragma mark - socket file descriptor
218 
219 
220 static status_t
221 socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer,
222 	size_t *_length)
223 {
224 	ssize_t bytesRead = sStackInterface->recv(descriptor->u.socket, buffer,
225 		*_length, 0);
226 	*_length = bytesRead >= 0 ? bytesRead : 0;
227 	return bytesRead >= 0 ? B_OK : bytesRead;
228 }
229 
230 
231 static status_t
232 socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer,
233 	size_t *_length)
234 {
235 	ssize_t bytesWritten = sStackInterface->send(descriptor->u.socket, buffer,
236 		*_length, 0);
237 	*_length = bytesWritten >= 0 ? bytesWritten : 0;
238 	return bytesWritten >= 0 ? B_OK : bytesWritten;
239 }
240 
241 
242 static status_t
243 socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer,
244 	size_t length)
245 {
246 	return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length);
247 }
248 
249 
250 static status_t
251 socket_set_flags(struct file_descriptor *descriptor, int flags)
252 {
253 	// we ignore O_APPEND, but O_NONBLOCK we need to translate
254 	uint32 op = (flags & O_NONBLOCK) != 0
255 		? B_SET_NONBLOCKING_IO : B_SET_BLOCKING_IO;
256 
257 	return sStackInterface->ioctl(descriptor->u.socket, op, NULL, 0);
258 }
259 
260 
261 static status_t
262 socket_select(struct file_descriptor *descriptor, uint8 event,
263 	struct selectsync *sync)
264 {
265 	return sStackInterface->select(descriptor->u.socket, event, sync);
266 }
267 
268 
269 static status_t
270 socket_deselect(struct file_descriptor *descriptor, uint8 event,
271 	struct selectsync *sync)
272 {
273 	return sStackInterface->deselect(descriptor->u.socket, event, sync);
274 }
275 
276 
277 static status_t
278 socket_read_stat(struct file_descriptor *descriptor, struct stat *st)
279 {
280 	st->st_dev = 0;
281 	st->st_ino = (addr_t)descriptor->u.socket;
282 	st->st_mode = S_IFSOCK | 0666;
283 	st->st_nlink = 1;
284 	st->st_uid = 0;
285 	st->st_gid = 0;
286 	st->st_size = 0;
287 	st->st_rdev = 0;
288 	st->st_blksize = 1024;	// use MTU for datagram sockets?
289 	time_t now = time(NULL);
290 	st->st_atime = now;
291 	st->st_mtime = now;
292 	st->st_ctime = now;
293 	st->st_crtime = now;
294 	st->st_type = 0;
295 
296 	return B_OK;
297 }
298 
299 
300 static status_t
301 socket_close(struct file_descriptor *descriptor)
302 {
303 	return sStackInterface->close(descriptor->u.socket);
304 }
305 
306 
307 static void
308 socket_free(struct file_descriptor *descriptor)
309 {
310 	sStackInterface->free(descriptor->u.socket);
311 }
312 
313 
314 static struct fd_ops sSocketFDOps = {
315 	&socket_read,
316 	&socket_write,
317 	NULL,	// fd_seek
318 	&socket_ioctl,
319 	&socket_set_flags,
320 	&socket_select,
321 	&socket_deselect,
322 	NULL,	// fd_read_dir
323 	NULL,	// fd_rewind_dir
324 	&socket_read_stat,
325 	NULL,	// fd_write_stat
326 	&socket_close,
327 	&socket_free
328 };
329 
330 
331 static int
332 create_socket_fd(net_socket* socket, bool kernel)
333 {
334 	// Get the socket's non-blocking flag, so we can set the respective
335 	// open mode flag.
336 	int32 nonBlock;
337 	socklen_t nonBlockLen = sizeof(int32);
338 	status_t error = sStackInterface->getsockopt(socket, SOL_SOCKET,
339 		SO_NONBLOCK, &nonBlock, &nonBlockLen);
340 	if (error != B_OK)
341 		return error;
342 
343 	// allocate a file descriptor
344 	file_descriptor* descriptor = alloc_fd();
345 	if (descriptor == NULL)
346 		return B_NO_MEMORY;
347 
348 	// init it
349 	descriptor->type = FDTYPE_SOCKET;
350 	descriptor->ops = &sSocketFDOps;
351 	descriptor->u.socket = socket;
352 	descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0);
353 
354 	// publish it
355 	int fd = new_fd(get_current_io_context(kernel), descriptor);
356 	if (fd < 0)
357 		free(descriptor);
358 
359 	return fd;
360 }
361 
362 
363 // #pragma mark - common sockets API implementation
364 
365 
366 static int
367 common_socket(int family, int type, int protocol, bool kernel)
368 {
369 	if (!get_stack_interface_module())
370 		return B_UNSUPPORTED;
371 
372 	// create the socket
373 	net_socket* socket;
374 	status_t error = sStackInterface->open(family, type, protocol, &socket);
375 	if (error != B_OK)
376 		return error;
377 
378 	// allocate the FD
379 	int fd = create_socket_fd(socket, kernel);
380 	if (fd < 0) {
381 		sStackInterface->close(socket);
382 		sStackInterface->free(socket);
383 	}
384 
385 	return fd;
386 }
387 
388 
389 static status_t
390 common_bind(int fd, const struct sockaddr *address, socklen_t addressLength,
391 	bool kernel)
392 {
393 	file_descriptor* descriptor;
394 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
395 	FDPutter _(descriptor);
396 
397 	return sStackInterface->bind(descriptor->u.socket, address, addressLength);
398 }
399 
400 
401 static status_t
402 common_shutdown(int fd, int how, bool kernel)
403 {
404 	file_descriptor* descriptor;
405 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
406 	FDPutter _(descriptor);
407 
408 	return sStackInterface->shutdown(descriptor->u.socket, how);
409 }
410 
411 
412 static status_t
413 common_connect(int fd, const struct sockaddr *address,
414 	socklen_t addressLength, bool kernel)
415 {
416 	file_descriptor* descriptor;
417 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
418 	FDPutter _(descriptor);
419 
420 	return sStackInterface->connect(descriptor->u.socket, address,
421 		addressLength);
422 }
423 
424 
425 static status_t
426 common_listen(int fd, int backlog, bool kernel)
427 {
428 	file_descriptor* descriptor;
429 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
430 	FDPutter _(descriptor);
431 
432 	return sStackInterface->listen(descriptor->u.socket, backlog);
433 }
434 
435 
436 static int
437 common_accept(int fd, struct sockaddr *address, socklen_t *_addressLength,
438 	bool kernel)
439 {
440 	file_descriptor* descriptor;
441 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
442 	FDPutter _(descriptor);
443 
444 	net_socket* acceptedSocket;
445 	status_t error = sStackInterface->accept(descriptor->u.socket, address,
446 		_addressLength, &acceptedSocket);
447 	if (error != B_OK)
448 		return error;
449 
450 	// allocate the FD
451 	int acceptedFD = create_socket_fd(acceptedSocket, kernel);
452 	if (acceptedFD < 0) {
453 		sStackInterface->close(acceptedSocket);
454 		sStackInterface->free(acceptedSocket);
455 	}
456 
457 	return acceptedFD;
458 }
459 
460 
461 static ssize_t
462 common_recv(int fd, void *data, size_t length, int flags, bool kernel)
463 {
464 	file_descriptor* descriptor;
465 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
466 	FDPutter _(descriptor);
467 
468 	return sStackInterface->recv(descriptor->u.socket, data, length, flags);
469 }
470 
471 
472 static ssize_t
473 common_recvfrom(int fd, void *data, size_t length, int flags,
474 	struct sockaddr *address, socklen_t *_addressLength, bool kernel)
475 {
476 	file_descriptor* descriptor;
477 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
478 	FDPutter _(descriptor);
479 
480 	return sStackInterface->recvfrom(descriptor->u.socket, data, length,
481 		flags, address, _addressLength);
482 }
483 
484 
485 static ssize_t
486 common_recvmsg(int fd, struct msghdr *message, int flags, bool kernel)
487 {
488 	file_descriptor* descriptor;
489 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
490 	FDPutter _(descriptor);
491 
492 	return sStackInterface->recvmsg(descriptor->u.socket, message, flags);
493 }
494 
495 
496 static ssize_t
497 common_send(int fd, const void *data, size_t length, int flags, bool kernel)
498 {
499 	file_descriptor* descriptor;
500 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
501 	FDPutter _(descriptor);
502 
503 	return sStackInterface->send(descriptor->u.socket, data, length, flags);
504 }
505 
506 
507 static ssize_t
508 common_sendto(int fd, const void *data, size_t length, int flags,
509 	const struct sockaddr *address, socklen_t addressLength, bool kernel)
510 {
511 	file_descriptor* descriptor;
512 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
513 	FDPutter _(descriptor);
514 
515 	return sStackInterface->sendto(descriptor->u.socket, data, length, flags,
516 		address, addressLength);
517 }
518 
519 
520 static ssize_t
521 common_sendmsg(int fd, const struct msghdr *message, int flags, bool kernel)
522 {
523 	file_descriptor* descriptor;
524 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
525 	FDPutter _(descriptor);
526 
527 	return sStackInterface->sendmsg(descriptor->u.socket, message, flags);
528 }
529 
530 
531 static status_t
532 common_getsockopt(int fd, int level, int option, void *value,
533 	socklen_t *_length, bool kernel)
534 {
535 	file_descriptor* descriptor;
536 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
537 	FDPutter _(descriptor);
538 
539 	return sStackInterface->getsockopt(descriptor->u.socket, level, option,
540 		value, _length);
541 }
542 
543 
544 static status_t
545 common_setsockopt(int fd, int level, int option, const void *value,
546 	socklen_t length, bool kernel)
547 {
548 	file_descriptor* descriptor;
549 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
550 	FDPutter _(descriptor);
551 
552 	return sStackInterface->setsockopt(descriptor->u.socket, level, option,
553 		value, length);
554 }
555 
556 
557 static status_t
558 common_getpeername(int fd, struct sockaddr *address,
559 	socklen_t *_addressLength, bool kernel)
560 {
561 	file_descriptor* descriptor;
562 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
563 	FDPutter _(descriptor);
564 
565 	return sStackInterface->getpeername(descriptor->u.socket, address,
566 		_addressLength);
567 }
568 
569 
570 static status_t
571 common_getsockname(int fd, struct sockaddr *address,
572 	socklen_t *_addressLength, bool kernel)
573 {
574 	file_descriptor* descriptor;
575 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
576 	FDPutter _(descriptor);
577 
578 	return sStackInterface->getsockname(descriptor->u.socket, address,
579 		_addressLength);
580 }
581 
582 
583 static int
584 common_sockatmark(int fd, bool kernel)
585 {
586 	file_descriptor* descriptor;
587 	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
588 	FDPutter _(descriptor);
589 
590 	return sStackInterface->sockatmark(descriptor->u.socket);
591 }
592 
593 
594 static status_t
595 common_socketpair(int family, int type, int protocol, int fds[2], bool kernel)
596 {
597 	if (!get_stack_interface_module())
598 		return B_UNSUPPORTED;
599 
600 	net_socket* sockets[2];
601 	status_t error = sStackInterface->socketpair(family, type, protocol,
602 		sockets);
603 	if (error != B_OK)
604 		return error;
605 
606 	// allocate the FDs
607 	for (int i = 0; i < 2; i++) {
608 		fds[i] = create_socket_fd(sockets[i], kernel);
609 		if (fds[i] < 0) {
610 			sStackInterface->close(sockets[i]);
611 			sStackInterface->free(sockets[i]);
612 			return fds[i];
613 		}
614 	}
615 
616 	return B_OK;
617 }
618 
619 
620 static status_t
621 common_get_next_socket_stat(int family, uint32 *cookie, struct net_stat *stat)
622 {
623 	if (!get_stack_interface_module())
624 		return B_UNSUPPORTED;
625 
626 	return sStackInterface->get_next_socket_stat(family, cookie, stat);
627 }
628 
629 
630 // #pragma mark - kernel sockets API
631 
632 
633 int
634 socket(int family, int type, int protocol)
635 {
636 	SyscallFlagUnsetter _;
637 	RETURN_AND_SET_ERRNO(common_socket(family, type, protocol, true));
638 }
639 
640 
641 int
642 bind(int socket, const struct sockaddr *address, socklen_t addressLength)
643 {
644 	SyscallFlagUnsetter _;
645 	RETURN_AND_SET_ERRNO(common_bind(socket, address, addressLength, true));
646 }
647 
648 
649 int
650 shutdown(int socket, int how)
651 {
652 	SyscallFlagUnsetter _;
653 	RETURN_AND_SET_ERRNO(common_shutdown(socket, how, true));
654 }
655 
656 
657 int
658 connect(int socket, const struct sockaddr *address, socklen_t addressLength)
659 {
660 	SyscallFlagUnsetter _;
661 	RETURN_AND_SET_ERRNO(common_connect(socket, address, addressLength, true));
662 }
663 
664 
665 int
666 listen(int socket, int backlog)
667 {
668 	SyscallFlagUnsetter _;
669 	RETURN_AND_SET_ERRNO(common_listen(socket, backlog, true));
670 }
671 
672 
673 int
674 accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
675 {
676 	SyscallFlagUnsetter _;
677 	RETURN_AND_SET_ERRNO(common_accept(socket, address, _addressLength, true));
678 }
679 
680 
681 ssize_t
682 recv(int socket, void *data, size_t length, int flags)
683 {
684 	SyscallFlagUnsetter _;
685 	RETURN_AND_SET_ERRNO(common_recv(socket, data, length, flags, true));
686 }
687 
688 
689 ssize_t
690 recvfrom(int socket, void *data, size_t length, int flags,
691 	struct sockaddr *address, socklen_t *_addressLength)
692 {
693 	SyscallFlagUnsetter _;
694 	RETURN_AND_SET_ERRNO(common_recvfrom(socket, data, length, flags, address,
695 		_addressLength, true));
696 }
697 
698 
699 ssize_t
700 recvmsg(int socket, struct msghdr *message, int flags)
701 {
702 	SyscallFlagUnsetter _;
703 	RETURN_AND_SET_ERRNO(common_recvmsg(socket, message, flags, true));
704 }
705 
706 
707 ssize_t
708 send(int socket, const void *data, size_t length, int flags)
709 {
710 	SyscallFlagUnsetter _;
711 	RETURN_AND_SET_ERRNO(common_send(socket, data, length, flags, true));
712 }
713 
714 
715 ssize_t
716 sendto(int socket, const void *data, size_t length, int flags,
717 	const struct sockaddr *address, socklen_t addressLength)
718 {
719 	SyscallFlagUnsetter _;
720 	RETURN_AND_SET_ERRNO(common_sendto(socket, data, length, flags, address,
721 		addressLength, true));
722 }
723 
724 
725 ssize_t
726 sendmsg(int socket, const struct msghdr *message, int flags)
727 {
728 	SyscallFlagUnsetter _;
729 	RETURN_AND_SET_ERRNO(common_sendmsg(socket, message, flags, true));
730 }
731 
732 
733 int
734 getsockopt(int socket, int level, int option, void *value, socklen_t *_length)
735 {
736 	SyscallFlagUnsetter _;
737 	RETURN_AND_SET_ERRNO(common_getsockopt(socket, level, option, value,
738 		_length, true));
739 }
740 
741 
742 int
743 setsockopt(int socket, int level, int option, const void *value,
744 	socklen_t length)
745 {
746 	SyscallFlagUnsetter _;
747 	RETURN_AND_SET_ERRNO(common_setsockopt(socket, level, option, value,
748 		length, true));
749 }
750 
751 
752 int
753 getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
754 {
755 	SyscallFlagUnsetter _;
756 	RETURN_AND_SET_ERRNO(common_getpeername(socket, address, _addressLength,
757 		true));
758 }
759 
760 
761 int
762 getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
763 {
764 	SyscallFlagUnsetter _;
765 	RETURN_AND_SET_ERRNO(common_getsockname(socket, address, _addressLength,
766 		true));
767 }
768 
769 
770 int
771 sockatmark(int socket)
772 {
773 	SyscallFlagUnsetter _;
774 	RETURN_AND_SET_ERRNO(common_sockatmark(socket, true));
775 }
776 
777 
778 int
779 socketpair(int family, int type, int protocol, int socketVector[2])
780 {
781 	SyscallFlagUnsetter _;
782 	RETURN_AND_SET_ERRNO(common_socketpair(family, type, protocol,
783 		socketVector, true));
784 }
785 
786 
787 // #pragma mark - syscalls
788 
789 
790 int
791 _user_socket(int family, int type, int protocol)
792 {
793 	SyscallRestartWrapper<int> result;
794 	return result = common_socket(family, type, protocol, false);
795 }
796 
797 
798 status_t
799 _user_bind(int socket, const struct sockaddr *userAddress,
800 	socklen_t addressLength)
801 {
802 	// check parameters and copy address from userland
803 	if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LEN)
804 		return B_BAD_VALUE;
805 
806 	char address[MAX_SOCKET_ADDRESS_LEN];
807 	if (!IS_USER_ADDRESS(userAddress)
808 			|| user_memcpy(address, userAddress, addressLength) != B_OK) {
809 		return B_BAD_ADDRESS;
810 	}
811 
812 	SyscallRestartWrapper<status_t> error;
813 	return error = common_bind(socket, (sockaddr*)address, addressLength,
814 		false);
815 }
816 
817 
818 status_t
819 _user_shutdown_socket(int socket, int how)
820 {
821 	SyscallRestartWrapper<status_t> error;
822 	return error = common_shutdown(socket, how, false);
823 }
824 
825 
826 status_t
827 _user_connect(int socket, const struct sockaddr *userAddress,
828 	socklen_t addressLength)
829 {
830 	// check parameters and copy address from userland
831 	if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LEN)
832 		return B_BAD_VALUE;
833 
834 	char address[MAX_SOCKET_ADDRESS_LEN];
835 	if (!IS_USER_ADDRESS(userAddress)
836 			|| user_memcpy(address, userAddress, addressLength) != B_OK) {
837 		return B_BAD_ADDRESS;
838 	}
839 
840 	SyscallRestartWrapper<status_t> error;
841 
842 	return error = common_connect(socket, (sockaddr*)address, addressLength,
843 		false);
844 }
845 
846 
847 status_t
848 _user_listen(int socket, int backlog)
849 {
850 	SyscallRestartWrapper<status_t> error;
851 	return error = common_listen(socket, backlog, false);
852 }
853 
854 
855 int
856 _user_accept(int socket, struct sockaddr *userAddress,
857 	socklen_t *_addressLength)
858 {
859 	// check parameters
860 	socklen_t addressLength = 0;
861 	status_t error = prepare_userland_address_result(userAddress,
862 		_addressLength, addressLength, false);
863 	if (error != B_OK)
864 		return error;
865 
866 	// accept()
867 	SyscallRestartWrapper<int> result;
868 
869 	char address[MAX_SOCKET_ADDRESS_LEN];
870 	socklen_t userAddressBufferSize = addressLength;
871 	result = common_accept(socket,
872 		userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
873 
874 	// copy address size and address back to userland
875 	if (copy_address_to_userland(address, addressLength, userAddress,
876 			userAddressBufferSize, _addressLength) != B_OK) {
877 		_user_close(result);
878 		return B_BAD_ADDRESS;
879 	}
880 
881 	return result;
882 }
883 
884 
885 ssize_t
886 _user_recv(int socket, void *data, size_t length, int flags)
887 {
888 	SyscallRestartWrapper<ssize_t> result;
889 	return result = common_recv(socket, data, length, flags, false);
890 }
891 
892 
893 ssize_t
894 _user_recvfrom(int socket, void *data, size_t length, int flags,
895 	struct sockaddr *userAddress, socklen_t *_addressLength)
896 {
897 	// check parameters
898 	socklen_t addressLength = 0;
899 	status_t error = prepare_userland_address_result(userAddress,
900 		_addressLength, addressLength, false);
901 	if (error != B_OK)
902 		return error;
903 
904 	// recvfrom()
905 	SyscallRestartWrapper<ssize_t> result;
906 
907 	char address[MAX_SOCKET_ADDRESS_LEN];
908 	socklen_t userAddressBufferSize = addressLength;
909 	result = common_recvfrom(socket, data, length, flags,
910 		userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
911 	if (result < 0)
912 		return result;
913 
914 	// copy address size and address back to userland
915 	if (copy_address_to_userland(address, addressLength, userAddress,
916 			userAddressBufferSize, _addressLength) != B_OK) {
917 		return B_BAD_ADDRESS;
918 	}
919 
920 	return result;
921 }
922 
923 
924 ssize_t
925 _user_recvmsg(int socket, struct msghdr *userMessage, int flags)
926 {
927 	// copy message from userland
928 	msghdr message;
929 	iovec* userVecs;
930 	MemoryDeleter vecsDeleter;
931 	void* userAddress;
932 	char address[MAX_SOCKET_ADDRESS_LEN];
933 
934 	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
935 		vecsDeleter, userAddress, address);
936 	if (error != B_OK)
937 		return error;
938 
939 	// prepare a buffer for ancillary data
940 	MemoryDeleter ancillaryDeleter;
941 	void* ancillary = NULL;
942 	void* userAncillary = message.msg_control;
943 	if (userAncillary != NULL) {
944 		if (!IS_USER_ADDRESS(userAncillary))
945 			return B_BAD_ADDRESS;
946 		if (message.msg_controllen < 0)
947 			return B_BAD_VALUE;
948 		if (message.msg_controllen > MAX_ANCILLARY_DATA_LEN)
949 			message.msg_controllen = MAX_ANCILLARY_DATA_LEN;
950 
951 		message.msg_control = ancillary = malloc(message.msg_controllen);
952 		if (message.msg_control == NULL)
953 			return B_NO_MEMORY;
954 
955 		ancillaryDeleter.SetTo(ancillary);
956 	}
957 
958 	// recvmsg()
959 	SyscallRestartWrapper<ssize_t> result;
960 
961 	result = common_recvmsg(socket, &message, flags, false);
962 	if (result < 0)
963 		return result;
964 
965 	// copy the address, the ancillary data, and the message header back to
966 	// userland
967 	message.msg_name = userAddress;
968 	message.msg_iov = userVecs;
969 	message.msg_control = userAncillary;
970 	if (userAddress != NULL && user_memcpy(userAddress, address,
971 				message.msg_namelen) != B_OK
972 		|| userAncillary != NULL && user_memcpy(userAncillary, ancillary,
973 				message.msg_controllen) != B_OK
974 		|| user_memcpy(userMessage, &message, sizeof(msghdr)) != B_OK) {
975 		return B_BAD_ADDRESS;
976 	}
977 
978 	return result;
979 }
980 
981 
982 ssize_t
983 _user_send(int socket, const void *data, size_t length, int flags)
984 {
985 	SyscallRestartWrapper<ssize_t> result;
986 	return result = common_send(socket, data, length, flags, false);
987 }
988 
989 
990 ssize_t
991 _user_sendto(int socket, const void *data, size_t length, int flags,
992 	const struct sockaddr *userAddress, socklen_t addressLength)
993 {
994 // TODO: If this is a connection-mode socket, the address parameter is
995 // supposed to be ignored.
996 	if (userAddress == NULL || addressLength <= 0
997 			|| addressLength > MAX_SOCKET_ADDRESS_LEN) {
998 		return B_BAD_VALUE;
999 	}
1000 
1001 	// copy address from userland
1002 	char address[MAX_SOCKET_ADDRESS_LEN];
1003 	if (!IS_USER_ADDRESS(userAddress)
1004 			|| user_memcpy(address, userAddress, addressLength) != B_OK) {
1005 		return B_BAD_ADDRESS;
1006 	}
1007 
1008 	// sendto()
1009 	SyscallRestartWrapper<ssize_t> result;
1010 
1011 	return result = common_sendto(socket, data, length, flags,
1012 		(sockaddr*)address, addressLength, false);
1013 }
1014 
1015 
1016 ssize_t
1017 _user_sendmsg(int socket, const struct msghdr *userMessage, int flags)
1018 {
1019 	// copy message from userland
1020 	msghdr message;
1021 	iovec* userVecs;
1022 	MemoryDeleter vecsDeleter;
1023 	void* userAddress;
1024 	char address[MAX_SOCKET_ADDRESS_LEN];
1025 
1026 	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
1027 		vecsDeleter, userAddress, address);
1028 	if (error != B_OK)
1029 		return error;
1030 
1031 	// copy the address from userland
1032 	if (userAddress != NULL
1033 			&& user_memcpy(address, userAddress, message.msg_namelen) != B_OK) {
1034 		return B_BAD_ADDRESS;
1035 	}
1036 
1037 	// copy ancillary data from userland
1038 	MemoryDeleter ancillaryDeleter;
1039 	void* userAncillary = message.msg_control;
1040 	if (userAncillary != NULL) {
1041 		if (!IS_USER_ADDRESS(userAncillary))
1042 			return B_BAD_ADDRESS;
1043 		if (message.msg_controllen < 0
1044 				|| message.msg_controllen > MAX_ANCILLARY_DATA_LEN) {
1045 			return B_BAD_VALUE;
1046 		}
1047 
1048 		message.msg_control = malloc(message.msg_controllen);
1049 		if (message.msg_control == NULL)
1050 			return B_NO_MEMORY;
1051 		ancillaryDeleter.SetTo(message.msg_control);
1052 
1053 		if (user_memcpy(message.msg_control, userAncillary,
1054 				message.msg_controllen) != B_OK) {
1055 			return B_BAD_ADDRESS;
1056 		}
1057 	}
1058 
1059 	// sendmsg()
1060 	SyscallRestartWrapper<ssize_t> result;
1061 
1062 	return result = common_sendmsg(socket, &message, flags, false);
1063 }
1064 
1065 
1066 status_t
1067 _user_getsockopt(int socket, int level, int option, void *userValue,
1068 	socklen_t *_length)
1069 {
1070 	// check params
1071 	if (userValue == NULL || _length == NULL)
1072 		return B_BAD_VALUE;
1073 	if (!IS_USER_ADDRESS(userValue) || !IS_USER_ADDRESS(_length))
1074 		return B_BAD_ADDRESS;
1075 
1076 	// copy length from userland
1077 	socklen_t length;
1078 	if (user_memcpy(&length, _length, sizeof(socklen_t)) != B_OK)
1079 		return B_BAD_ADDRESS;
1080 
1081 	if (length > MAX_SOCKET_OPTION_LEN)
1082 		return B_BAD_VALUE;
1083 
1084 	// getsockopt()
1085 	char value[MAX_SOCKET_OPTION_LEN];
1086 	SyscallRestartWrapper<status_t> error;
1087 	error = common_getsockopt(socket, level, option, value, &length,
1088 		false);
1089 	if (error != B_OK)
1090 		return error;
1091 
1092 	// copy value back to userland
1093 	if (user_memcpy(userValue, value, length) != B_OK)
1094 		return B_BAD_ADDRESS;
1095 
1096 	return B_OK;
1097 }
1098 
1099 
1100 status_t
1101 _user_setsockopt(int socket, int level, int option, const void *userValue,
1102 	socklen_t length)
1103 {
1104 	// check params
1105 	if (userValue == NULL || length > MAX_SOCKET_OPTION_LEN)
1106 		return B_BAD_VALUE;
1107 
1108 	// copy value from userland
1109 	char value[MAX_SOCKET_OPTION_LEN];
1110 	if (!IS_USER_ADDRESS(userValue)
1111 			|| user_memcpy(value, userValue, length) != B_OK) {
1112 		return B_BAD_ADDRESS;
1113 	}
1114 
1115 	// setsockopt();
1116 	SyscallRestartWrapper<status_t> error;
1117 	return error = common_setsockopt(socket, level, option, value, length,
1118 		false);
1119 }
1120 
1121 
1122 status_t
1123 _user_getpeername(int socket, struct sockaddr *userAddress,
1124 	socklen_t *_addressLength)
1125 {
1126 	// check parameters
1127 	socklen_t addressLength = 0;
1128 	SyscallRestartWrapper<status_t> error;
1129 	error = prepare_userland_address_result(userAddress, _addressLength,
1130 		addressLength, true);
1131 	if (error != B_OK)
1132 		return error;
1133 
1134 	// getpeername()
1135 	char address[MAX_SOCKET_ADDRESS_LEN];
1136 	socklen_t userAddressBufferSize = addressLength;
1137 	error = common_getpeername(socket, (sockaddr*)address, &addressLength,
1138 		false);
1139 	if (error != B_OK)
1140 		return error;
1141 
1142 	// copy address size and address back to userland
1143 	if (copy_address_to_userland(address, addressLength, userAddress,
1144 			userAddressBufferSize, _addressLength) != B_OK) {
1145 		return B_BAD_ADDRESS;
1146 	}
1147 
1148 	return B_OK;
1149 }
1150 
1151 
1152 status_t
1153 _user_getsockname(int socket, struct sockaddr *userAddress,
1154 	socklen_t *_addressLength)
1155 {
1156 	// check parameters
1157 	socklen_t addressLength = 0;
1158 	SyscallRestartWrapper<status_t> error;
1159 	error = prepare_userland_address_result(userAddress, _addressLength,
1160 		addressLength, true);
1161 	if (error != B_OK)
1162 		return error;
1163 
1164 	// getsockname()
1165 	char address[MAX_SOCKET_ADDRESS_LEN];
1166 	socklen_t userAddressBufferSize = addressLength;
1167 	error = common_getsockname(socket, (sockaddr*)address, &addressLength,
1168 		false);
1169 	if (error != B_OK)
1170 		return error;
1171 
1172 	// copy address size and address back to userland
1173 	if (copy_address_to_userland(address, addressLength, userAddress,
1174 			userAddressBufferSize, _addressLength) != B_OK) {
1175 		return B_BAD_ADDRESS;
1176 	}
1177 
1178 	return B_OK;
1179 }
1180 
1181 
1182 int
1183 _user_sockatmark(int socket)
1184 {
1185 	SyscallRestartWrapper<status_t> error;
1186 	return error = common_sockatmark(socket, false);
1187 }
1188 
1189 
1190 status_t
1191 _user_socketpair(int family, int type, int protocol, int *userSocketVector)
1192 {
1193 	// check parameters
1194 	if (userSocketVector == NULL)
1195 		return B_BAD_VALUE;
1196 	if (!IS_USER_ADDRESS(userSocketVector))
1197 		return B_BAD_ADDRESS;
1198 
1199 	// socketpair()
1200 	int socketVector[2];
1201 	SyscallRestartWrapper<status_t> error;
1202 	error = common_socketpair(family, type, protocol, socketVector, false);
1203 	if (error != B_OK)
1204 		return error;
1205 
1206 	// copy FDs back to userland
1207 	if (user_memcpy(userSocketVector, socketVector,
1208 			sizeof(socketVector)) != B_OK) {
1209 		_user_close(socketVector[0]);
1210 		_user_close(socketVector[1]);
1211 		return B_BAD_ADDRESS;
1212 	}
1213 
1214 	return B_OK;
1215 }
1216 
1217 
1218 status_t
1219 _user_get_next_socket_stat(int family, uint32 *_cookie, struct net_stat *_stat)
1220 {
1221 	// check parameters and copy cookie from userland
1222 	if (_cookie == NULL || _stat == NULL)
1223 		return B_BAD_VALUE;
1224 
1225 	uint32 cookie;
1226 	if (!IS_USER_ADDRESS(_stat) || !IS_USER_ADDRESS(_cookie)
1227 			|| user_memcpy(&cookie, _cookie, sizeof(cookie)) != B_OK) {
1228 		return B_BAD_ADDRESS;
1229 	}
1230 
1231 	net_stat stat;
1232 	SyscallRestartWrapper<status_t> error;
1233 	error = common_get_next_socket_stat(family, &cookie, &stat);
1234 	if (error != B_OK)
1235 		return error;
1236 
1237 	// copy cookie and data back to userland
1238 	if (user_memcpy(_cookie, &cookie, sizeof(cookie)) != B_OK
1239 		|| user_memcpy(_stat, &stat, sizeof(net_stat)) != B_OK) {
1240 		return B_BAD_ADDRESS;
1241 	}
1242 
1243 	return B_OK;
1244 }
1245