btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / system / kernel / fs / socket.cpp
blobe62ef60bda6765933f1129637918cc4a57214531
1 /*
2 * Copyright 2009-2010, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
5 * Distributed under the terms of the MIT License.
6 */
9 #include <sys/socket.h>
11 #include <errno.h>
12 #include <limits.h>
14 #include <module.h>
16 #include <AutoDeleter.h>
18 #include <syscall_utils.h>
20 #include <fd.h>
21 #include <kernel.h>
22 #include <lock.h>
23 #include <syscall_restart.h>
24 #include <util/AutoLock.h>
25 #include <vfs.h>
27 #include <net_stack_interface.h>
28 #include <net_stat.h>
31 #define MAX_SOCKET_ADDRESS_LENGTH (sizeof(sockaddr_storage))
32 #define MAX_SOCKET_OPTION_LENGTH 128
33 #define MAX_ANCILLARY_DATA_LENGTH 1024
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)
43 static net_stack_interface_module_info* sStackInterface = NULL;
44 static vint32 sStackInterfaceInitialized = 0;
45 static mutex sLock = MUTEX_INITIALIZER("stack interface");
48 struct FDPutter {
49 FDPutter(file_descriptor* descriptor)
50 : descriptor(descriptor)
54 ~FDPutter()
56 if (descriptor != NULL)
57 put_fd(descriptor);
60 file_descriptor* descriptor;
64 static net_stack_interface_module_info*
65 get_stack_interface_module()
67 MutexLocker _(sLock);
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;
81 return sStackInterface;
85 static void
86 put_stack_interface_module()
88 MutexLocker _(sLock);
90 if (sStackInterfaceInitialized-- == 1)
91 put_module(NET_STACK_INTERFACE_MODULE_NAME);
95 static status_t
96 prepare_userland_address_result(struct sockaddr* userAddress,
97 socklen_t* _addressLength, socklen_t& addressLength, bool addressRequired)
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;
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;
118 if (addressLength > MAX_SOCKET_ADDRESS_LENGTH)
119 addressLength = MAX_SOCKET_ADDRESS_LENGTH;
121 return B_OK;
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)
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;
139 return B_OK;
143 static status_t
144 prepare_userland_msghdr(const msghdr* userMessage, msghdr& message,
145 iovec*& userVecs, MemoryDeleter& vecsDeleter, void*& userAddress,
146 char* address)
148 if (userMessage == NULL)
149 return B_BAD_VALUE;
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;
157 userVecs = message.msg_iov;
158 userAddress = message.msg_name;
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 = (iovec*)malloc(sizeof(iovec) * message.msg_iovlen);
165 if (vecs == NULL)
166 return B_NO_MEMORY;
167 vecsDeleter.SetTo(vecs);
169 if (!IS_USER_ADDRESS(message.msg_iov)
170 || user_memcpy(vecs, message.msg_iov,
171 message.msg_iovlen * sizeof(iovec)) != B_OK) {
172 return B_BAD_ADDRESS;
175 for (int i = 0; i < message.msg_iovlen; i++) {
176 if (!IS_USER_ADDRESS(vecs[i].iov_base))
177 return B_BAD_ADDRESS;
180 message.msg_iov = vecs;
181 } else {
182 message.msg_iov = NULL;
183 message.msg_iovlen = 0;
186 // prepare the address field
187 userAddress = message.msg_name;
188 if (userAddress != NULL) {
189 if (!IS_USER_ADDRESS(message.msg_name))
190 return B_BAD_ADDRESS;
191 if (message.msg_namelen > MAX_SOCKET_ADDRESS_LENGTH)
192 message.msg_namelen = MAX_SOCKET_ADDRESS_LENGTH;
194 message.msg_name = address;
197 return B_OK;
201 static status_t
202 get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor)
204 if (fd < 0)
205 return EBADF;
207 descriptor = get_fd(get_current_io_context(kernel), fd);
208 if (descriptor == NULL)
209 return EBADF;
211 if (descriptor->type != FDTYPE_SOCKET) {
212 put_fd(descriptor);
213 return ENOTSOCK;
216 return B_OK;
220 // #pragma mark - socket file descriptor
223 static status_t
224 socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer,
225 size_t *_length)
227 ssize_t bytesRead = sStackInterface->recv(descriptor->u.socket, buffer,
228 *_length, 0);
229 *_length = bytesRead >= 0 ? bytesRead : 0;
230 return bytesRead >= 0 ? B_OK : bytesRead;
234 static status_t
235 socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer,
236 size_t *_length)
238 ssize_t bytesWritten = sStackInterface->send(descriptor->u.socket, buffer,
239 *_length, 0);
240 *_length = bytesWritten >= 0 ? bytesWritten : 0;
241 return bytesWritten >= 0 ? B_OK : bytesWritten;
245 static status_t
246 socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer,
247 size_t length)
249 return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length);
253 static status_t
254 socket_set_flags(struct file_descriptor *descriptor, int flags)
256 // we ignore O_APPEND, but O_NONBLOCK we need to translate
257 uint32 op = (flags & O_NONBLOCK) != 0
258 ? B_SET_NONBLOCKING_IO : B_SET_BLOCKING_IO;
260 return sStackInterface->ioctl(descriptor->u.socket, op, NULL, 0);
264 static status_t
265 socket_select(struct file_descriptor *descriptor, uint8 event,
266 struct selectsync *sync)
268 return sStackInterface->select(descriptor->u.socket, event, sync);
272 static status_t
273 socket_deselect(struct file_descriptor *descriptor, uint8 event,
274 struct selectsync *sync)
276 return sStackInterface->deselect(descriptor->u.socket, event, sync);
280 static status_t
281 socket_read_stat(struct file_descriptor *descriptor, struct stat *st)
283 st->st_dev = 0;
284 st->st_ino = (addr_t)descriptor->u.socket;
285 st->st_mode = S_IFSOCK | 0666;
286 st->st_nlink = 1;
287 st->st_uid = 0;
288 st->st_gid = 0;
289 st->st_size = 0;
290 st->st_rdev = 0;
291 st->st_blksize = 1024; // use MTU for datagram sockets?
292 st->st_type = 0;
294 timespec now;
295 now.tv_sec = time(NULL);
296 now.tv_nsec = 0;
298 st->st_atim = now;
299 st->st_mtim = now;
300 st->st_ctim = now;
301 st->st_crtim = now;
303 return B_OK;
307 static status_t
308 socket_close(struct file_descriptor *descriptor)
310 return sStackInterface->close(descriptor->u.socket);
314 static void
315 socket_free(struct file_descriptor *descriptor)
317 sStackInterface->free(descriptor->u.socket);
318 put_stack_interface_module();
322 static struct fd_ops sSocketFDOps = {
323 &socket_read,
324 &socket_write,
325 NULL, // fd_seek
326 &socket_ioctl,
327 &socket_set_flags,
328 &socket_select,
329 &socket_deselect,
330 NULL, // fd_read_dir
331 NULL, // fd_rewind_dir
332 &socket_read_stat,
333 NULL, // fd_write_stat
334 &socket_close,
335 &socket_free
339 static int
340 create_socket_fd(net_socket* socket, bool kernel)
342 // Get the socket's non-blocking flag, so we can set the respective
343 // open mode flag.
344 int32 nonBlock;
345 socklen_t nonBlockLen = sizeof(int32);
346 status_t error = sStackInterface->getsockopt(socket, SOL_SOCKET,
347 SO_NONBLOCK, &nonBlock, &nonBlockLen);
348 if (error != B_OK)
349 return error;
351 // allocate a file descriptor
352 file_descriptor* descriptor = alloc_fd();
353 if (descriptor == NULL)
354 return B_NO_MEMORY;
356 // init it
357 descriptor->type = FDTYPE_SOCKET;
358 descriptor->ops = &sSocketFDOps;
359 descriptor->u.socket = socket;
360 descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0);
362 // publish it
363 int fd = new_fd(get_current_io_context(kernel), descriptor);
364 if (fd < 0)
365 free(descriptor);
367 return fd;
371 // #pragma mark - common sockets API implementation
374 static int
375 common_socket(int family, int type, int protocol, bool kernel)
377 if (!get_stack_interface_module())
378 return B_UNSUPPORTED;
380 // create the socket
381 net_socket* socket;
382 status_t error = sStackInterface->open(family, type, protocol, &socket);
383 if (error != B_OK) {
384 put_stack_interface_module();
385 return error;
388 // allocate the FD
389 int fd = create_socket_fd(socket, kernel);
390 if (fd < 0) {
391 sStackInterface->close(socket);
392 sStackInterface->free(socket);
393 put_stack_interface_module();
396 return fd;
400 static status_t
401 common_bind(int fd, const struct sockaddr *address, socklen_t addressLength,
402 bool kernel)
404 file_descriptor* descriptor;
405 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
406 FDPutter _(descriptor);
408 return sStackInterface->bind(descriptor->u.socket, address, addressLength);
412 static status_t
413 common_shutdown(int fd, int how, bool kernel)
415 file_descriptor* descriptor;
416 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
417 FDPutter _(descriptor);
419 return sStackInterface->shutdown(descriptor->u.socket, how);
423 static status_t
424 common_connect(int fd, const struct sockaddr *address,
425 socklen_t addressLength, bool kernel)
427 file_descriptor* descriptor;
428 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
429 FDPutter _(descriptor);
431 return sStackInterface->connect(descriptor->u.socket, address,
432 addressLength);
436 static status_t
437 common_listen(int fd, int backlog, bool kernel)
439 file_descriptor* descriptor;
440 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
441 FDPutter _(descriptor);
443 return sStackInterface->listen(descriptor->u.socket, backlog);
447 static int
448 common_accept(int fd, struct sockaddr *address, socklen_t *_addressLength,
449 bool kernel)
451 file_descriptor* descriptor;
452 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
453 FDPutter _(descriptor);
455 net_socket* acceptedSocket;
456 status_t error = sStackInterface->accept(descriptor->u.socket, address,
457 _addressLength, &acceptedSocket);
458 if (error != B_OK)
459 return error;
461 // allocate the FD
462 int acceptedFD = create_socket_fd(acceptedSocket, kernel);
463 if (acceptedFD < 0) {
464 sStackInterface->close(acceptedSocket);
465 sStackInterface->free(acceptedSocket);
466 } else {
467 // we need a reference for the new FD
468 get_stack_interface_module();
471 return acceptedFD;
475 static ssize_t
476 common_recv(int fd, void *data, size_t length, int flags, bool kernel)
478 file_descriptor* descriptor;
479 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
480 FDPutter _(descriptor);
482 return sStackInterface->recv(descriptor->u.socket, data, length, flags);
486 static ssize_t
487 common_recvfrom(int fd, void *data, size_t length, int flags,
488 struct sockaddr *address, socklen_t *_addressLength, bool kernel)
490 file_descriptor* descriptor;
491 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
492 FDPutter _(descriptor);
494 return sStackInterface->recvfrom(descriptor->u.socket, data, length,
495 flags, address, _addressLength);
499 static ssize_t
500 common_recvmsg(int fd, struct msghdr *message, int flags, bool kernel)
502 file_descriptor* descriptor;
503 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
504 FDPutter _(descriptor);
506 return sStackInterface->recvmsg(descriptor->u.socket, message, flags);
510 static ssize_t
511 common_send(int fd, const void *data, size_t length, int flags, bool kernel)
513 file_descriptor* descriptor;
514 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
515 FDPutter _(descriptor);
517 return sStackInterface->send(descriptor->u.socket, data, length, flags);
521 static ssize_t
522 common_sendto(int fd, const void *data, size_t length, int flags,
523 const struct sockaddr *address, socklen_t addressLength, bool kernel)
525 file_descriptor* descriptor;
526 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
527 FDPutter _(descriptor);
529 return sStackInterface->sendto(descriptor->u.socket, data, length, flags,
530 address, addressLength);
534 static ssize_t
535 common_sendmsg(int fd, const struct msghdr *message, int flags, bool kernel)
537 file_descriptor* descriptor;
538 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
539 FDPutter _(descriptor);
541 return sStackInterface->sendmsg(descriptor->u.socket, message, flags);
545 static status_t
546 common_getsockopt(int fd, int level, int option, void *value,
547 socklen_t *_length, bool kernel)
549 file_descriptor* descriptor;
550 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
551 FDPutter _(descriptor);
553 return sStackInterface->getsockopt(descriptor->u.socket, level, option,
554 value, _length);
558 static status_t
559 common_setsockopt(int fd, int level, int option, const void *value,
560 socklen_t length, bool kernel)
562 file_descriptor* descriptor;
563 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
564 FDPutter _(descriptor);
566 return sStackInterface->setsockopt(descriptor->u.socket, level, option,
567 value, length);
571 static status_t
572 common_getpeername(int fd, struct sockaddr *address,
573 socklen_t *_addressLength, bool kernel)
575 file_descriptor* descriptor;
576 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
577 FDPutter _(descriptor);
579 return sStackInterface->getpeername(descriptor->u.socket, address,
580 _addressLength);
584 static status_t
585 common_getsockname(int fd, struct sockaddr *address,
586 socklen_t *_addressLength, bool kernel)
588 file_descriptor* descriptor;
589 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
590 FDPutter _(descriptor);
592 return sStackInterface->getsockname(descriptor->u.socket, address,
593 _addressLength);
597 static int
598 common_sockatmark(int fd, bool kernel)
600 file_descriptor* descriptor;
601 GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
602 FDPutter _(descriptor);
604 return sStackInterface->sockatmark(descriptor->u.socket);
608 static status_t
609 common_socketpair(int family, int type, int protocol, int fds[2], bool kernel)
611 if (!get_stack_interface_module())
612 return B_UNSUPPORTED;
614 net_socket* sockets[2];
615 status_t error = sStackInterface->socketpair(family, type, protocol,
616 sockets);
617 if (error != B_OK) {
618 put_stack_interface_module();
619 return error;
622 // allocate the FDs
623 for (int i = 0; i < 2; i++) {
624 fds[i] = create_socket_fd(sockets[i], kernel);
625 if (fds[i] < 0) {
626 sStackInterface->close(sockets[i]);
627 sStackInterface->free(sockets[i]);
628 put_stack_interface_module();
629 return fds[i];
633 // We need another reference for the second socket
634 get_stack_interface_module();
635 return B_OK;
639 static status_t
640 common_get_next_socket_stat(int family, uint32 *cookie, struct net_stat *stat)
642 if (!get_stack_interface_module())
643 return B_UNSUPPORTED;
645 status_t status = sStackInterface->get_next_socket_stat(family, cookie,
646 stat);
648 put_stack_interface_module();
649 return status;
653 // #pragma mark - kernel sockets API
657 socket(int family, int type, int protocol)
659 SyscallFlagUnsetter _;
660 RETURN_AND_SET_ERRNO(common_socket(family, type, protocol, true));
665 bind(int socket, const struct sockaddr *address, socklen_t addressLength)
667 SyscallFlagUnsetter _;
668 RETURN_AND_SET_ERRNO(common_bind(socket, address, addressLength, true));
673 shutdown(int socket, int how)
675 SyscallFlagUnsetter _;
676 RETURN_AND_SET_ERRNO(common_shutdown(socket, how, true));
681 connect(int socket, const struct sockaddr *address, socklen_t addressLength)
683 SyscallFlagUnsetter _;
684 RETURN_AND_SET_ERRNO(common_connect(socket, address, addressLength, true));
689 listen(int socket, int backlog)
691 SyscallFlagUnsetter _;
692 RETURN_AND_SET_ERRNO(common_listen(socket, backlog, true));
697 accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
699 SyscallFlagUnsetter _;
700 RETURN_AND_SET_ERRNO(common_accept(socket, address, _addressLength, true));
704 ssize_t
705 recv(int socket, void *data, size_t length, int flags)
707 SyscallFlagUnsetter _;
708 RETURN_AND_SET_ERRNO(common_recv(socket, data, length, flags, true));
712 ssize_t
713 recvfrom(int socket, void *data, size_t length, int flags,
714 struct sockaddr *address, socklen_t *_addressLength)
716 SyscallFlagUnsetter _;
717 RETURN_AND_SET_ERRNO(common_recvfrom(socket, data, length, flags, address,
718 _addressLength, true));
722 ssize_t
723 recvmsg(int socket, struct msghdr *message, int flags)
725 SyscallFlagUnsetter _;
726 RETURN_AND_SET_ERRNO(common_recvmsg(socket, message, flags, true));
730 ssize_t
731 send(int socket, const void *data, size_t length, int flags)
733 SyscallFlagUnsetter _;
734 RETURN_AND_SET_ERRNO(common_send(socket, data, length, flags, true));
738 ssize_t
739 sendto(int socket, const void *data, size_t length, int flags,
740 const struct sockaddr *address, socklen_t addressLength)
742 SyscallFlagUnsetter _;
743 RETURN_AND_SET_ERRNO(common_sendto(socket, data, length, flags, address,
744 addressLength, true));
748 ssize_t
749 sendmsg(int socket, const struct msghdr *message, int flags)
751 SyscallFlagUnsetter _;
752 RETURN_AND_SET_ERRNO(common_sendmsg(socket, message, flags, true));
757 getsockopt(int socket, int level, int option, void *value, socklen_t *_length)
759 SyscallFlagUnsetter _;
760 RETURN_AND_SET_ERRNO(common_getsockopt(socket, level, option, value,
761 _length, true));
766 setsockopt(int socket, int level, int option, const void *value,
767 socklen_t length)
769 SyscallFlagUnsetter _;
770 RETURN_AND_SET_ERRNO(common_setsockopt(socket, level, option, value,
771 length, true));
776 getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
778 SyscallFlagUnsetter _;
779 RETURN_AND_SET_ERRNO(common_getpeername(socket, address, _addressLength,
780 true));
785 getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
787 SyscallFlagUnsetter _;
788 RETURN_AND_SET_ERRNO(common_getsockname(socket, address, _addressLength,
789 true));
794 sockatmark(int socket)
796 SyscallFlagUnsetter _;
797 RETURN_AND_SET_ERRNO(common_sockatmark(socket, true));
802 socketpair(int family, int type, int protocol, int socketVector[2])
804 SyscallFlagUnsetter _;
805 RETURN_AND_SET_ERRNO(common_socketpair(family, type, protocol,
806 socketVector, true));
810 // #pragma mark - syscalls
814 _user_socket(int family, int type, int protocol)
816 SyscallRestartWrapper<int> result;
817 return result = common_socket(family, type, protocol, false);
821 status_t
822 _user_bind(int socket, const struct sockaddr *userAddress,
823 socklen_t addressLength)
825 // check parameters and copy address from userland
826 if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LENGTH)
827 return B_BAD_VALUE;
829 sockaddr_storage address;
830 memset(&address, 0, sizeof(address));
831 if (!IS_USER_ADDRESS(userAddress)
832 || user_memcpy(&address, userAddress, addressLength) != B_OK) {
833 return B_BAD_ADDRESS;
836 address.ss_len = addressLength;
837 // make sure the sa_len field is set correctly
839 SyscallRestartWrapper<status_t> error;
840 return error = common_bind(socket, (sockaddr*)&address, addressLength,
841 false);
845 status_t
846 _user_shutdown_socket(int socket, int how)
848 SyscallRestartWrapper<status_t> error;
849 return error = common_shutdown(socket, how, false);
853 status_t
854 _user_connect(int socket, const struct sockaddr *userAddress,
855 socklen_t addressLength)
857 // check parameters and copy address from userland
858 if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LENGTH)
859 return B_BAD_VALUE;
861 sockaddr_storage address;
862 memset(&address, 0, sizeof(address));
863 if (!IS_USER_ADDRESS(userAddress)
864 || user_memcpy(&address, userAddress, addressLength) != B_OK) {
865 return B_BAD_ADDRESS;
868 address.ss_len = addressLength;
869 // make sure the sa_len field is set correctly
871 SyscallRestartWrapper<status_t> error;
873 return error = common_connect(socket, (sockaddr*)&address, addressLength,
874 false);
878 status_t
879 _user_listen(int socket, int backlog)
881 SyscallRestartWrapper<status_t> error;
882 return error = common_listen(socket, backlog, false);
887 _user_accept(int socket, struct sockaddr *userAddress,
888 socklen_t *_addressLength)
890 // check parameters
891 socklen_t addressLength = 0;
892 status_t error = prepare_userland_address_result(userAddress,
893 _addressLength, addressLength, false);
894 if (error != B_OK)
895 return error;
897 // accept()
898 SyscallRestartWrapper<int> result;
900 char address[MAX_SOCKET_ADDRESS_LENGTH];
901 socklen_t userAddressBufferSize = addressLength;
902 result = common_accept(socket,
903 userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
905 // copy address size and address back to userland
906 if (copy_address_to_userland(address, addressLength, userAddress,
907 userAddressBufferSize, _addressLength) != B_OK) {
908 _user_close(result);
909 return B_BAD_ADDRESS;
912 return result;
916 ssize_t
917 _user_recv(int socket, void *data, size_t length, int flags)
919 if (data == NULL || !IS_USER_ADDRESS(data))
920 return B_BAD_ADDRESS;
922 SyscallRestartWrapper<ssize_t> result;
923 return result = common_recv(socket, data, length, flags, false);
927 ssize_t
928 _user_recvfrom(int socket, void *data, size_t length, int flags,
929 struct sockaddr *userAddress, socklen_t *_addressLength)
931 if (data == NULL || !IS_USER_ADDRESS(data))
932 return B_BAD_ADDRESS;
934 // check parameters
935 socklen_t addressLength = 0;
936 status_t error = prepare_userland_address_result(userAddress,
937 _addressLength, addressLength, false);
938 if (error != B_OK)
939 return error;
941 // recvfrom()
942 SyscallRestartWrapper<ssize_t> result;
944 char address[MAX_SOCKET_ADDRESS_LENGTH];
945 socklen_t userAddressBufferSize = addressLength;
946 result = common_recvfrom(socket, data, length, flags,
947 userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
948 if (result < 0)
949 return result;
951 // copy address size and address back to userland
952 if (copy_address_to_userland(address, addressLength, userAddress,
953 userAddressBufferSize, _addressLength) != B_OK) {
954 return B_BAD_ADDRESS;
957 return result;
961 ssize_t
962 _user_recvmsg(int socket, struct msghdr *userMessage, int flags)
964 // copy message from userland
965 msghdr message;
966 iovec* userVecs;
967 MemoryDeleter vecsDeleter;
968 void* userAddress;
969 char address[MAX_SOCKET_ADDRESS_LENGTH];
971 status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
972 vecsDeleter, userAddress, address);
973 if (error != B_OK)
974 return error;
976 // prepare a buffer for ancillary data
977 MemoryDeleter ancillaryDeleter;
978 void* ancillary = NULL;
979 void* userAncillary = message.msg_control;
980 if (userAncillary != NULL) {
981 if (!IS_USER_ADDRESS(userAncillary))
982 return B_BAD_ADDRESS;
983 if (message.msg_controllen < 0)
984 return B_BAD_VALUE;
985 if (message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH)
986 message.msg_controllen = MAX_ANCILLARY_DATA_LENGTH;
988 message.msg_control = ancillary = malloc(message.msg_controllen);
989 if (message.msg_control == NULL)
990 return B_NO_MEMORY;
992 ancillaryDeleter.SetTo(ancillary);
995 // recvmsg()
996 SyscallRestartWrapper<ssize_t> result;
998 result = common_recvmsg(socket, &message, flags, false);
999 if (result < 0)
1000 return result;
1002 // copy the address, the ancillary data, and the message header back to
1003 // userland
1004 message.msg_name = userAddress;
1005 message.msg_iov = userVecs;
1006 message.msg_control = userAncillary;
1007 if ((userAddress != NULL && user_memcpy(userAddress, address,
1008 message.msg_namelen) != B_OK)
1009 || (userAncillary != NULL && user_memcpy(userAncillary, ancillary,
1010 message.msg_controllen) != B_OK)
1011 || user_memcpy(userMessage, &message, sizeof(msghdr)) != B_OK) {
1012 return B_BAD_ADDRESS;
1015 return result;
1019 ssize_t
1020 _user_send(int socket, const void *data, size_t length, int flags)
1022 if (data == NULL || !IS_USER_ADDRESS(data))
1023 return B_BAD_ADDRESS;
1025 SyscallRestartWrapper<ssize_t> result;
1026 return result = common_send(socket, data, length, flags, false);
1030 ssize_t
1031 _user_sendto(int socket, const void *data, size_t length, int flags,
1032 const struct sockaddr *userAddress, socklen_t addressLength)
1034 if (data == NULL || !IS_USER_ADDRESS(data))
1035 return B_BAD_ADDRESS;
1037 // TODO: If this is a connection-mode socket, the address parameter is
1038 // supposed to be ignored.
1039 if (userAddress == NULL || addressLength <= 0
1040 || addressLength > MAX_SOCKET_ADDRESS_LENGTH) {
1041 return B_BAD_VALUE;
1044 // copy address from userland
1045 char address[MAX_SOCKET_ADDRESS_LENGTH];
1046 if (!IS_USER_ADDRESS(userAddress)
1047 || user_memcpy(address, userAddress, addressLength) != B_OK) {
1048 return B_BAD_ADDRESS;
1051 // sendto()
1052 SyscallRestartWrapper<ssize_t> result;
1054 return result = common_sendto(socket, data, length, flags,
1055 (sockaddr*)address, addressLength, false);
1059 ssize_t
1060 _user_sendmsg(int socket, const struct msghdr *userMessage, int flags)
1062 // copy message from userland
1063 msghdr message;
1064 iovec* userVecs;
1065 MemoryDeleter vecsDeleter;
1066 void* userAddress;
1067 char address[MAX_SOCKET_ADDRESS_LENGTH];
1069 status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
1070 vecsDeleter, userAddress, address);
1071 if (error != B_OK)
1072 return error;
1074 // copy the address from userland
1075 if (userAddress != NULL
1076 && user_memcpy(address, userAddress, message.msg_namelen) != B_OK) {
1077 return B_BAD_ADDRESS;
1080 // copy ancillary data from userland
1081 MemoryDeleter ancillaryDeleter;
1082 void* userAncillary = message.msg_control;
1083 if (userAncillary != NULL) {
1084 if (!IS_USER_ADDRESS(userAncillary))
1085 return B_BAD_ADDRESS;
1086 if (message.msg_controllen < 0
1087 || message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH) {
1088 return B_BAD_VALUE;
1091 message.msg_control = malloc(message.msg_controllen);
1092 if (message.msg_control == NULL)
1093 return B_NO_MEMORY;
1094 ancillaryDeleter.SetTo(message.msg_control);
1096 if (user_memcpy(message.msg_control, userAncillary,
1097 message.msg_controllen) != B_OK) {
1098 return B_BAD_ADDRESS;
1102 // sendmsg()
1103 SyscallRestartWrapper<ssize_t> result;
1105 return result = common_sendmsg(socket, &message, flags, false);
1109 status_t
1110 _user_getsockopt(int socket, int level, int option, void *userValue,
1111 socklen_t *_length)
1113 // check params
1114 if (userValue == NULL || _length == NULL)
1115 return B_BAD_VALUE;
1116 if (!IS_USER_ADDRESS(userValue) || !IS_USER_ADDRESS(_length))
1117 return B_BAD_ADDRESS;
1119 // copy length from userland
1120 socklen_t length;
1121 if (user_memcpy(&length, _length, sizeof(socklen_t)) != B_OK)
1122 return B_BAD_ADDRESS;
1124 if (length > MAX_SOCKET_OPTION_LENGTH)
1125 return B_BAD_VALUE;
1127 // getsockopt()
1128 char value[MAX_SOCKET_OPTION_LENGTH];
1129 SyscallRestartWrapper<status_t> error;
1130 error = common_getsockopt(socket, level, option, value, &length,
1131 false);
1132 if (error != B_OK)
1133 return error;
1135 // copy value back to userland
1136 if (user_memcpy(userValue, value, length) != B_OK)
1137 return B_BAD_ADDRESS;
1139 return B_OK;
1143 status_t
1144 _user_setsockopt(int socket, int level, int option, const void *userValue,
1145 socklen_t length)
1147 // check params
1148 if (userValue == NULL || length > MAX_SOCKET_OPTION_LENGTH)
1149 return B_BAD_VALUE;
1151 // copy value from userland
1152 char value[MAX_SOCKET_OPTION_LENGTH];
1153 if (!IS_USER_ADDRESS(userValue)
1154 || user_memcpy(value, userValue, length) != B_OK) {
1155 return B_BAD_ADDRESS;
1158 // setsockopt();
1159 SyscallRestartWrapper<status_t> error;
1160 return error = common_setsockopt(socket, level, option, value, length,
1161 false);
1165 status_t
1166 _user_getpeername(int socket, struct sockaddr *userAddress,
1167 socklen_t *_addressLength)
1169 // check parameters
1170 socklen_t addressLength = 0;
1171 SyscallRestartWrapper<status_t> error;
1172 error = prepare_userland_address_result(userAddress, _addressLength,
1173 addressLength, true);
1174 if (error != B_OK)
1175 return error;
1177 // getpeername()
1178 char address[MAX_SOCKET_ADDRESS_LENGTH];
1179 socklen_t userAddressBufferSize = addressLength;
1180 error = common_getpeername(socket, (sockaddr*)address, &addressLength,
1181 false);
1182 if (error != B_OK)
1183 return error;
1185 // copy address size and address back to userland
1186 if (copy_address_to_userland(address, addressLength, userAddress,
1187 userAddressBufferSize, _addressLength) != B_OK) {
1188 return B_BAD_ADDRESS;
1191 return B_OK;
1195 status_t
1196 _user_getsockname(int socket, struct sockaddr *userAddress,
1197 socklen_t *_addressLength)
1199 // check parameters
1200 socklen_t addressLength = 0;
1201 SyscallRestartWrapper<status_t> error;
1202 error = prepare_userland_address_result(userAddress, _addressLength,
1203 addressLength, true);
1204 if (error != B_OK)
1205 return error;
1207 // getsockname()
1208 char address[MAX_SOCKET_ADDRESS_LENGTH];
1209 socklen_t userAddressBufferSize = addressLength;
1210 error = common_getsockname(socket, (sockaddr*)address, &addressLength,
1211 false);
1212 if (error != B_OK)
1213 return error;
1215 // copy address size and address back to userland
1216 if (copy_address_to_userland(address, addressLength, userAddress,
1217 userAddressBufferSize, _addressLength) != B_OK) {
1218 return B_BAD_ADDRESS;
1221 return B_OK;
1226 _user_sockatmark(int socket)
1228 SyscallRestartWrapper<status_t> error;
1229 return error = common_sockatmark(socket, false);
1233 status_t
1234 _user_socketpair(int family, int type, int protocol, int *userSocketVector)
1236 // check parameters
1237 if (userSocketVector == NULL)
1238 return B_BAD_VALUE;
1239 if (!IS_USER_ADDRESS(userSocketVector))
1240 return B_BAD_ADDRESS;
1242 // socketpair()
1243 int socketVector[2];
1244 SyscallRestartWrapper<status_t> error;
1245 error = common_socketpair(family, type, protocol, socketVector, false);
1246 if (error != B_OK)
1247 return error;
1249 // copy FDs back to userland
1250 if (user_memcpy(userSocketVector, socketVector,
1251 sizeof(socketVector)) != B_OK) {
1252 _user_close(socketVector[0]);
1253 _user_close(socketVector[1]);
1254 return B_BAD_ADDRESS;
1257 return B_OK;
1261 status_t
1262 _user_get_next_socket_stat(int family, uint32 *_cookie, struct net_stat *_stat)
1264 // check parameters and copy cookie from userland
1265 if (_cookie == NULL || _stat == NULL)
1266 return B_BAD_VALUE;
1268 uint32 cookie;
1269 if (!IS_USER_ADDRESS(_stat) || !IS_USER_ADDRESS(_cookie)
1270 || user_memcpy(&cookie, _cookie, sizeof(cookie)) != B_OK) {
1271 return B_BAD_ADDRESS;
1274 net_stat stat;
1275 SyscallRestartWrapper<status_t> error;
1276 error = common_get_next_socket_stat(family, &cookie, &stat);
1277 if (error != B_OK)
1278 return error;
1280 // copy cookie and data back to userland
1281 if (user_memcpy(_cookie, &cookie, sizeof(cookie)) != B_OK
1282 || user_memcpy(_stat, &stat, sizeof(net_stat)) != B_OK) {
1283 return B_BAD_ADDRESS;
1286 return B_OK;