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