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