1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "stack_private.h" 11 12 #include <stdlib.h> 13 #include <string.h> 14 #include <sys/ioctl.h> 15 #include <sys/time.h> 16 17 #include <new> 18 19 #include <Drivers.h> 20 #include <KernelExport.h> 21 #include <Select.h> 22 23 #include <AutoDeleter.h> 24 #include <team.h> 25 #include <util/AutoLock.h> 26 #include <util/list.h> 27 #include <WeakReferenceable.h> 28 29 #include <fs/select_sync_pool.h> 30 #include <kernel.h> 31 32 #include <net_protocol.h> 33 #include <net_stack.h> 34 #include <net_stat.h> 35 36 #include "ancillary_data.h" 37 #include "utility.h" 38 39 40 //#define TRACE_SOCKET 41 #ifdef TRACE_SOCKET 42 # define TRACE(x...) dprintf(STACK_DEBUG_PREFIX x) 43 #else 44 # define TRACE(x...) ; 45 #endif 46 47 48 struct net_socket_private; 49 typedef DoublyLinkedList<net_socket_private> SocketList; 50 51 struct net_socket_private : net_socket, 52 DoublyLinkedListLinkImpl<net_socket_private>, 53 BWeakReferenceable { 54 net_socket_private(); 55 ~net_socket_private(); 56 57 void RemoveFromParent(); 58 59 BWeakReference<net_socket_private> parent; 60 team_id owner; 61 uint32 max_backlog; 62 uint32 child_count; 63 SocketList pending_children; 64 SocketList connected_children; 65 66 struct select_sync_pool* select_pool; 67 mutex lock; 68 69 bool is_connected; 70 bool is_in_socket_list; 71 }; 72 73 74 int socket_bind(net_socket* socket, const struct sockaddr* address, 75 socklen_t addressLength); 76 int socket_setsockopt(net_socket* socket, int level, int option, 77 const void* value, int length); 78 ssize_t socket_read_avail(net_socket* socket); 79 80 static SocketList sSocketList; 81 static mutex sSocketLock; 82 83 84 net_socket_private::net_socket_private() 85 : 86 owner(-1), 87 max_backlog(0), 88 child_count(0), 89 select_pool(NULL), 90 is_connected(false), 91 is_in_socket_list(false) 92 { 93 first_protocol = NULL; 94 first_info = NULL; 95 options = 0; 96 linger = 0; 97 bound_to_device = 0; 98 error = 0; 99 100 address.ss_len = 0; 101 peer.ss_len = 0; 102 103 mutex_init(&lock, "socket"); 104 105 // set defaults (may be overridden by the protocols) 106 send.buffer_size = 65535; 107 send.low_water_mark = 1; 108 send.timeout = B_INFINITE_TIMEOUT; 109 receive.buffer_size = 65535; 110 receive.low_water_mark = 1; 111 receive.timeout = B_INFINITE_TIMEOUT; 112 } 113 114 115 net_socket_private::~net_socket_private() 116 { 117 TRACE("delete net_socket %p\n", this); 118 119 if (parent != NULL) 120 panic("socket still has a parent!"); 121 122 if (is_in_socket_list) { 123 MutexLocker _(sSocketLock); 124 sSocketList.Remove(this); 125 } 126 127 mutex_lock(&lock); 128 129 // also delete all children of this socket 130 while (net_socket_private* child = pending_children.RemoveHead()) { 131 child->RemoveFromParent(); 132 } 133 while (net_socket_private* child = connected_children.RemoveHead()) { 134 child->RemoveFromParent(); 135 } 136 137 mutex_unlock(&lock); 138 139 put_domain_protocols(this); 140 141 mutex_destroy(&lock); 142 } 143 144 145 void 146 net_socket_private::RemoveFromParent() 147 { 148 ASSERT(!is_in_socket_list && parent != NULL); 149 150 parent = NULL; 151 152 mutex_lock(&sSocketLock); 153 sSocketList.Add(this); 154 mutex_unlock(&sSocketLock); 155 156 is_in_socket_list = true; 157 158 ReleaseReference(); 159 } 160 161 162 // #pragma mark - 163 164 165 static status_t 166 create_socket(int family, int type, int protocol, net_socket_private** _socket) 167 { 168 struct net_socket_private* socket = new(std::nothrow) net_socket_private; 169 if (socket == NULL) 170 return B_NO_MEMORY; 171 status_t status = socket->InitCheck(); 172 if (status != B_OK) { 173 delete socket; 174 return status; 175 } 176 177 socket->family = family; 178 socket->type = type; 179 socket->protocol = protocol; 180 181 status = get_domain_protocols(socket); 182 if (status != B_OK) { 183 delete socket; 184 return status; 185 } 186 187 TRACE("create net_socket %p (%u.%u.%u):\n", socket, socket->family, 188 socket->type, socket->protocol); 189 190 #ifdef TRACE_SOCKET 191 net_protocol* current = socket->first_protocol; 192 for (int i = 0; current != NULL; current = current->next, i++) 193 TRACE(" [%d] %p %s\n", i, current, current->module->info.name); 194 #endif 195 196 *_socket = socket; 197 return B_OK; 198 } 199 200 201 static status_t 202 add_ancillary_data(net_socket* socket, ancillary_data_container* container, 203 void* data, size_t dataLen) 204 { 205 cmsghdr* header = (cmsghdr*)data; 206 207 if (dataLen == 0) 208 return B_OK; 209 210 if (socket->first_info->add_ancillary_data == NULL) 211 return B_NOT_SUPPORTED; 212 213 while (true) { 214 if (header->cmsg_len < CMSG_LEN(0) || header->cmsg_len > dataLen) 215 return B_BAD_VALUE; 216 217 status_t status = socket->first_info->add_ancillary_data( 218 socket->first_protocol, container, header); 219 if (status != B_OK) 220 return status; 221 222 if (dataLen <= _ALIGN(header->cmsg_len)) 223 break; 224 dataLen -= _ALIGN(header->cmsg_len); 225 header = (cmsghdr*)((uint8*)header + _ALIGN(header->cmsg_len)); 226 } 227 228 return B_OK; 229 } 230 231 232 static status_t 233 process_ancillary_data(net_socket* socket, ancillary_data_container* container, 234 msghdr* messageHeader) 235 { 236 uint8* dataBuffer = (uint8*)messageHeader->msg_control; 237 int dataBufferLen = messageHeader->msg_controllen; 238 239 if (container == NULL || dataBuffer == NULL) { 240 messageHeader->msg_controllen = 0; 241 return B_OK; 242 } 243 244 ancillary_data_header header; 245 void* data = NULL; 246 247 while ((data = next_ancillary_data(container, data, &header)) != NULL) { 248 if (socket->first_info->process_ancillary_data == NULL) 249 return B_NOT_SUPPORTED; 250 251 ssize_t bytesWritten = socket->first_info->process_ancillary_data( 252 socket->first_protocol, &header, data, dataBuffer, dataBufferLen); 253 if (bytesWritten < 0) 254 return bytesWritten; 255 256 dataBuffer += bytesWritten; 257 dataBufferLen -= bytesWritten; 258 } 259 260 messageHeader->msg_controllen -= dataBufferLen; 261 262 return B_OK; 263 } 264 265 266 static status_t 267 process_ancillary_data(net_socket* socket, 268 net_buffer* buffer, msghdr* messageHeader) 269 { 270 void *dataBuffer = messageHeader->msg_control; 271 ssize_t bytesWritten; 272 273 if (dataBuffer == NULL) { 274 messageHeader->msg_controllen = 0; 275 return B_OK; 276 } 277 278 if (socket->first_info->process_ancillary_data_no_container == NULL) 279 return B_NOT_SUPPORTED; 280 281 bytesWritten = socket->first_info->process_ancillary_data_no_container( 282 socket->first_protocol, buffer, dataBuffer, 283 messageHeader->msg_controllen); 284 if (bytesWritten < 0) 285 return bytesWritten; 286 messageHeader->msg_controllen = bytesWritten; 287 288 return B_OK; 289 } 290 291 292 static ssize_t 293 socket_receive_no_buffer(net_socket* socket, msghdr* header, void* data, 294 size_t length, int flags) 295 { 296 iovec stackVec = { data, length }; 297 iovec* vecs = header ? header->msg_iov : &stackVec; 298 int vecCount = header ? header->msg_iovlen : 1; 299 sockaddr* address = header ? (sockaddr*)header->msg_name : NULL; 300 socklen_t* addressLen = header ? &header->msg_namelen : NULL; 301 302 ancillary_data_container* ancillaryData = NULL; 303 ssize_t bytesRead = socket->first_info->read_data_no_buffer( 304 socket->first_protocol, vecs, vecCount, &ancillaryData, address, 305 addressLen, flags); 306 if (bytesRead < 0) 307 return bytesRead; 308 309 CObjectDeleter< 310 ancillary_data_container, void, delete_ancillary_data_container> 311 ancillaryDataDeleter(ancillaryData); 312 313 // process ancillary data 314 if (header != NULL) { 315 status_t status = process_ancillary_data(socket, ancillaryData, header); 316 if (status != B_OK) 317 return status; 318 319 header->msg_flags = 0; 320 } 321 322 return bytesRead; 323 } 324 325 326 #if ENABLE_DEBUGGER_COMMANDS 327 328 329 static void 330 print_socket_line(net_socket_private* socket, const char* prefix) 331 { 332 BReference<net_socket_private> parent = socket->parent.GetReference(); 333 kprintf("%s%p %2d.%2d.%2d %6" B_PRId32 " %p %p %p%s\n", prefix, socket, 334 socket->family, socket->type, socket->protocol, socket->owner, 335 socket->first_protocol, socket->first_info, parent.Get(), 336 parent.IsSet() ? socket->is_connected ? " (c)" : " (p)" : ""); 337 } 338 339 340 static int 341 dump_socket(int argc, char** argv) 342 { 343 if (argc < 2) { 344 kprintf("usage: %s [address]\n", argv[0]); 345 return 0; 346 } 347 348 net_socket_private* socket = (net_socket_private*)parse_expression(argv[1]); 349 350 kprintf("SOCKET %p\n", socket); 351 kprintf(" family.type.protocol: %d.%d.%d\n", 352 socket->family, socket->type, socket->protocol); 353 BReference<net_socket_private> parent = socket->parent.GetReference(); 354 kprintf(" parent: %p\n", parent.Get()); 355 kprintf(" first protocol: %p\n", socket->first_protocol); 356 kprintf(" first module_info: %p\n", socket->first_info); 357 kprintf(" options: %x\n", socket->options); 358 kprintf(" linger: %d\n", socket->linger); 359 kprintf(" bound to device: %" B_PRIu32 "\n", socket->bound_to_device); 360 kprintf(" owner: %" B_PRId32 "\n", socket->owner); 361 kprintf(" max backlog: %" B_PRId32 "\n", socket->max_backlog); 362 kprintf(" is connected: %d\n", socket->is_connected); 363 kprintf(" child_count: %" B_PRIu32 "\n", socket->child_count); 364 365 if (socket->child_count == 0) 366 return 0; 367 368 kprintf(" pending children:\n"); 369 SocketList::Iterator iterator = socket->pending_children.GetIterator(); 370 while (net_socket_private* child = iterator.Next()) { 371 print_socket_line(child, " "); 372 } 373 374 kprintf(" connected children:\n"); 375 iterator = socket->connected_children.GetIterator(); 376 while (net_socket_private* child = iterator.Next()) { 377 print_socket_line(child, " "); 378 } 379 380 return 0; 381 } 382 383 384 static int 385 dump_sockets(int argc, char** argv) 386 { 387 kprintf("address kind owner protocol module_info parent\n"); 388 389 SocketList::Iterator iterator = sSocketList.GetIterator(); 390 while (net_socket_private* socket = iterator.Next()) { 391 print_socket_line(socket, ""); 392 393 SocketList::Iterator childIterator 394 = socket->pending_children.GetIterator(); 395 while (net_socket_private* child = childIterator.Next()) { 396 print_socket_line(child, " "); 397 } 398 399 childIterator = socket->connected_children.GetIterator(); 400 while (net_socket_private* child = childIterator.Next()) { 401 print_socket_line(child, " "); 402 } 403 } 404 405 return 0; 406 } 407 408 409 #endif // ENABLE_DEBUGGER_COMMANDS 410 411 412 // #pragma mark - 413 414 415 status_t 416 socket_open(int family, int type, int protocol, net_socket** _socket) 417 { 418 net_socket_private* socket; 419 status_t status = create_socket(family, type, protocol, &socket); 420 if (status != B_OK) 421 return status; 422 423 status = socket->first_info->open(socket->first_protocol); 424 if (status != B_OK) { 425 delete socket; 426 return status; 427 } 428 429 socket->owner = team_get_current_team_id(); 430 socket->is_in_socket_list = true; 431 432 mutex_lock(&sSocketLock); 433 sSocketList.Add(socket); 434 mutex_unlock(&sSocketLock); 435 436 *_socket = socket; 437 return B_OK; 438 } 439 440 441 status_t 442 socket_close(net_socket* _socket) 443 { 444 net_socket_private* socket = (net_socket_private*)_socket; 445 return socket->first_info->close(socket->first_protocol); 446 } 447 448 449 void 450 socket_free(net_socket* _socket) 451 { 452 net_socket_private* socket = (net_socket_private*)_socket; 453 socket->first_info->free(socket->first_protocol); 454 socket->ReleaseReference(); 455 } 456 457 458 status_t 459 socket_control(net_socket* socket, uint32 op, void* data, size_t length) 460 { 461 switch (op) { 462 case FIONBIO: 463 { 464 if (data == NULL) 465 return B_BAD_VALUE; 466 467 int value; 468 if (is_syscall()) { 469 if (!IS_USER_ADDRESS(data) 470 || user_memcpy(&value, data, sizeof(int)) != B_OK) { 471 return B_BAD_ADDRESS; 472 } 473 } else 474 value = *(int*)data; 475 476 return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value, 477 sizeof(int)); 478 } 479 480 case FIONREAD: 481 { 482 if (data == NULL || (socket->options & SO_ACCEPTCONN) != 0) 483 return B_BAD_VALUE; 484 485 int available = (int)socket_read_avail(socket); 486 if (available < 0) 487 available = 0; 488 489 if (is_syscall()) { 490 if (!IS_USER_ADDRESS(data) 491 || user_memcpy(data, &available, sizeof(available)) 492 != B_OK) { 493 return B_BAD_ADDRESS; 494 } 495 } else 496 *(int*)data = available; 497 498 return B_OK; 499 } 500 501 case B_SET_BLOCKING_IO: 502 case B_SET_NONBLOCKING_IO: 503 { 504 int value = op == B_SET_NONBLOCKING_IO; 505 return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value, 506 sizeof(int)); 507 } 508 } 509 510 return socket->first_info->control(socket->first_protocol, 511 LEVEL_DRIVER_IOCTL, op, data, &length); 512 } 513 514 515 ssize_t 516 socket_read_avail(net_socket* socket) 517 { 518 return socket->first_info->read_avail(socket->first_protocol); 519 } 520 521 522 ssize_t 523 socket_send_avail(net_socket* socket) 524 { 525 return socket->first_info->send_avail(socket->first_protocol); 526 } 527 528 529 status_t 530 socket_send_data(net_socket* socket, net_buffer* buffer) 531 { 532 return socket->first_info->send_data(socket->first_protocol, 533 buffer); 534 } 535 536 537 status_t 538 socket_receive_data(net_socket* socket, size_t length, uint32 flags, 539 net_buffer** _buffer) 540 { 541 status_t status = socket->first_info->read_data(socket->first_protocol, 542 length, flags, _buffer); 543 if (status != B_OK) 544 return status; 545 546 if (*_buffer && length < (*_buffer)->size) { 547 // discard any data behind the amount requested 548 gNetBufferModule.trim(*_buffer, length); 549 } 550 551 return status; 552 } 553 554 555 status_t 556 socket_get_next_stat(uint32* _cookie, int family, struct net_stat* stat) 557 { 558 MutexLocker locker(sSocketLock); 559 560 net_socket_private* socket = NULL; 561 SocketList::Iterator iterator = sSocketList.GetIterator(); 562 uint32 cookie = *_cookie; 563 uint32 count = 0; 564 565 while (true) { 566 socket = iterator.Next(); 567 if (socket == NULL) 568 return B_ENTRY_NOT_FOUND; 569 570 // TODO: also traverse the pending connections 571 if (count == cookie) 572 break; 573 574 if (family == -1 || family == socket->family) 575 count++; 576 } 577 578 *_cookie = count + 1; 579 580 stat->family = socket->family; 581 stat->type = socket->type; 582 stat->protocol = socket->protocol; 583 stat->owner = socket->owner; 584 stat->state[0] = '\0'; 585 memcpy(&stat->address, &socket->address, sizeof(struct sockaddr_storage)); 586 memcpy(&stat->peer, &socket->peer, sizeof(struct sockaddr_storage)); 587 stat->receive_queue_size = 0; 588 stat->send_queue_size = 0; 589 590 // fill in protocol specific data (if supported by the protocol) 591 size_t length = sizeof(net_stat); 592 socket->first_info->control(socket->first_protocol, socket->protocol, 593 NET_STAT_SOCKET, stat, &length); 594 595 return B_OK; 596 } 597 598 599 // #pragma mark - connections 600 601 602 bool 603 socket_acquire(net_socket* _socket) 604 { 605 net_socket_private* socket = (net_socket_private*)_socket; 606 607 // During destruction, the socket might still be accessible over its 608 // endpoint protocol. We need to make sure the endpoint cannot acquire the 609 // socket anymore -- while not obvious, the endpoint protocol is responsible 610 // for the proper locking here. 611 if (socket->CountReferences() == 0) 612 return false; 613 614 socket->AcquireReference(); 615 return true; 616 } 617 618 619 bool 620 socket_release(net_socket* _socket) 621 { 622 net_socket_private* socket = (net_socket_private*)_socket; 623 return socket->ReleaseReference(); 624 } 625 626 627 status_t 628 socket_spawn_pending(net_socket* _parent, net_socket** _socket) 629 { 630 net_socket_private* parent = (net_socket_private*)_parent; 631 632 TRACE("%s(%p)\n", __FUNCTION__, parent); 633 634 MutexLocker locker(parent->lock); 635 636 // We actually accept more pending connections to compensate for those 637 // that never complete, and also make sure at least a single connection 638 // can always be accepted 639 if (parent->child_count > 3 * parent->max_backlog / 2) 640 return ENOBUFS; 641 642 net_socket_private* socket; 643 status_t status = create_socket(parent->family, parent->type, 644 parent->protocol, &socket); 645 if (status != B_OK) 646 return status; 647 648 // inherit parent's properties 649 socket->send = parent->send; 650 socket->receive = parent->receive; 651 socket->options = parent->options & ~SO_ACCEPTCONN; 652 socket->linger = parent->linger; 653 socket->owner = parent->owner; 654 memcpy(&socket->address, &parent->address, parent->address.ss_len); 655 memcpy(&socket->peer, &parent->peer, parent->peer.ss_len); 656 657 // add to the parent's list of pending connections 658 parent->pending_children.Add(socket); 659 socket->parent = parent; 660 parent->child_count++; 661 662 *_socket = socket; 663 return B_OK; 664 } 665 666 667 /*! Dequeues a connected child from a parent socket. 668 It also returns a reference with the child socket. 669 */ 670 status_t 671 socket_dequeue_connected(net_socket* _parent, net_socket** _socket) 672 { 673 net_socket_private* parent = (net_socket_private*)_parent; 674 675 mutex_lock(&parent->lock); 676 677 net_socket_private* socket = parent->connected_children.RemoveHead(); 678 if (socket != NULL) { 679 socket->AcquireReference(); 680 socket->RemoveFromParent(); 681 parent->child_count--; 682 *_socket = socket; 683 } 684 685 mutex_unlock(&parent->lock); 686 687 if (socket == NULL) 688 return B_ENTRY_NOT_FOUND; 689 690 return B_OK; 691 } 692 693 694 ssize_t 695 socket_count_connected(net_socket* _parent) 696 { 697 net_socket_private* parent = (net_socket_private*)_parent; 698 699 MutexLocker _(parent->lock); 700 return parent->connected_children.Count(); 701 } 702 703 704 status_t 705 socket_set_max_backlog(net_socket* _socket, uint32 backlog) 706 { 707 net_socket_private* socket = (net_socket_private*)_socket; 708 709 // we enforce an upper limit of connections waiting to be accepted 710 if (backlog > 256) 711 backlog = 256; 712 713 MutexLocker _(socket->lock); 714 715 // first remove the pending connections, then the already connected 716 // ones as needed 717 net_socket_private* child; 718 while (socket->child_count > backlog 719 && (child = socket->pending_children.RemoveTail()) != NULL) { 720 child->RemoveFromParent(); 721 socket->child_count--; 722 } 723 while (socket->child_count > backlog 724 && (child = socket->connected_children.RemoveTail()) != NULL) { 725 child->RemoveFromParent(); 726 socket->child_count--; 727 } 728 729 socket->max_backlog = backlog; 730 return B_OK; 731 } 732 733 734 /*! Returns whether or not this socket has a parent. The parent might not be 735 valid anymore, though. 736 */ 737 bool 738 socket_has_parent(net_socket* _socket) 739 { 740 net_socket_private* socket = (net_socket_private*)_socket; 741 return socket->parent != NULL; 742 } 743 744 745 /*! The socket has been connected. It will be moved to the connected queue 746 of its parent socket. 747 */ 748 status_t 749 socket_connected(net_socket* _socket) 750 { 751 net_socket_private* socket = (net_socket_private*)_socket; 752 753 TRACE("socket_connected(%p)\n", socket); 754 755 if (socket->parent == NULL) { 756 socket->is_connected = true; 757 return B_OK; 758 } 759 760 BReference<net_socket_private> parent = socket->parent.GetReference(); 761 if (!parent.IsSet()) 762 return B_BAD_VALUE; 763 764 MutexLocker _(parent->lock); 765 766 parent->pending_children.Remove(socket); 767 parent->connected_children.Add(socket); 768 socket->is_connected = true; 769 770 // notify parent 771 if (parent->select_pool) 772 notify_select_event_pool(parent->select_pool, B_SELECT_READ); 773 774 return B_OK; 775 } 776 777 778 /*! The socket has been aborted. Steals the parent's reference, and releases 779 it. 780 */ 781 status_t 782 socket_aborted(net_socket* _socket) 783 { 784 net_socket_private* socket = (net_socket_private*)_socket; 785 786 TRACE("socket_aborted(%p)\n", socket); 787 788 BReference<net_socket_private> parent = socket->parent.GetReference(); 789 if (!parent.IsSet()) 790 return B_BAD_VALUE; 791 792 MutexLocker _(parent->lock); 793 794 if (socket->is_connected) 795 parent->connected_children.Remove(socket); 796 else 797 parent->pending_children.Remove(socket); 798 799 parent->child_count--; 800 socket->RemoveFromParent(); 801 802 return B_OK; 803 } 804 805 806 // #pragma mark - notifications 807 808 809 status_t 810 socket_request_notification(net_socket* _socket, uint8 event, selectsync* sync) 811 { 812 net_socket_private* socket = (net_socket_private*)_socket; 813 814 mutex_lock(&socket->lock); 815 816 status_t status = add_select_sync_pool_entry(&socket->select_pool, sync, 817 event); 818 819 mutex_unlock(&socket->lock); 820 821 if (status != B_OK) 822 return status; 823 824 // check if the event is already present 825 // TODO: add support for poll() types 826 827 switch (event) { 828 case B_SELECT_READ: 829 { 830 ssize_t available = socket_read_avail(socket); 831 if ((ssize_t)socket->receive.low_water_mark <= available 832 || available < B_OK) 833 notify_select_event(sync, event); 834 break; 835 } 836 case B_SELECT_WRITE: 837 { 838 if ((socket->options & SO_ACCEPTCONN) != 0) 839 break; 840 841 ssize_t available = socket_send_avail(socket); 842 if ((ssize_t)socket->send.low_water_mark <= available 843 || available < B_OK) 844 notify_select_event(sync, event); 845 break; 846 } 847 case B_SELECT_ERROR: 848 if (socket->error != B_OK) 849 notify_select_event(sync, event); 850 break; 851 } 852 853 return B_OK; 854 } 855 856 857 status_t 858 socket_cancel_notification(net_socket* _socket, uint8 event, selectsync* sync) 859 { 860 net_socket_private* socket = (net_socket_private*)_socket; 861 862 MutexLocker _(socket->lock); 863 return remove_select_sync_pool_entry(&socket->select_pool, sync, event); 864 } 865 866 867 status_t 868 socket_notify(net_socket* _socket, uint8 event, int32 value) 869 { 870 net_socket_private* socket = (net_socket_private*)_socket; 871 bool notify = true; 872 873 switch (event) { 874 case B_SELECT_READ: 875 if ((ssize_t)socket->receive.low_water_mark > value 876 && value >= B_OK) 877 notify = false; 878 break; 879 880 case B_SELECT_WRITE: 881 if ((ssize_t)socket->send.low_water_mark > value && value >= B_OK) 882 notify = false; 883 break; 884 885 case B_SELECT_ERROR: 886 socket->error = value; 887 break; 888 } 889 890 MutexLocker _(socket->lock); 891 892 if (notify && socket->select_pool != NULL) { 893 notify_select_event_pool(socket->select_pool, event); 894 895 if (event == B_SELECT_ERROR) { 896 // always notify read/write on error 897 notify_select_event_pool(socket->select_pool, B_SELECT_READ); 898 notify_select_event_pool(socket->select_pool, B_SELECT_WRITE); 899 } 900 } 901 902 return B_OK; 903 } 904 905 906 // #pragma mark - standard socket API 907 908 909 int 910 socket_accept(net_socket* socket, struct sockaddr* address, 911 socklen_t* _addressLength, net_socket** _acceptedSocket) 912 { 913 if ((socket->options & SO_ACCEPTCONN) == 0) 914 return B_BAD_VALUE; 915 916 net_socket* accepted; 917 status_t status = socket->first_info->accept(socket->first_protocol, 918 &accepted); 919 if (status != B_OK) 920 return status; 921 922 if (address && *_addressLength > 0) { 923 memcpy(address, &accepted->peer, min_c(*_addressLength, 924 min_c(accepted->peer.ss_len, sizeof(sockaddr_storage)))); 925 *_addressLength = accepted->peer.ss_len; 926 } 927 928 *_acceptedSocket = accepted; 929 return B_OK; 930 } 931 932 933 int 934 socket_bind(net_socket* socket, const struct sockaddr* address, 935 socklen_t addressLength) 936 { 937 sockaddr empty; 938 if (address == NULL) { 939 // special - try to bind to an empty address, like INADDR_ANY 940 memset(&empty, 0, sizeof(sockaddr)); 941 empty.sa_len = sizeof(sockaddr); 942 empty.sa_family = socket->family; 943 944 address = ∅ 945 addressLength = sizeof(sockaddr); 946 } 947 948 if (socket->address.ss_len != 0) 949 return B_BAD_VALUE; 950 951 memcpy(&socket->address, address, sizeof(sockaddr)); 952 socket->address.ss_len = sizeof(sockaddr_storage); 953 954 status_t status = socket->first_info->bind(socket->first_protocol, 955 (sockaddr*)address); 956 if (status != B_OK) { 957 // clear address again, as binding failed 958 socket->address.ss_len = 0; 959 } 960 961 return status; 962 } 963 964 965 int 966 socket_connect(net_socket* socket, const struct sockaddr* address, 967 socklen_t addressLength) 968 { 969 if (address == NULL || addressLength == 0) 970 return ENETUNREACH; 971 972 if (socket->address.ss_len == 0) { 973 // try to bind first 974 status_t status = socket_bind(socket, NULL, 0); 975 if (status != B_OK) 976 return status; 977 } 978 979 return socket->first_info->connect(socket->first_protocol, address); 980 } 981 982 983 int 984 socket_getpeername(net_socket* _socket, struct sockaddr* address, 985 socklen_t* _addressLength) 986 { 987 net_socket_private* socket = (net_socket_private*)_socket; 988 BReference<net_socket_private> parent = socket->parent.GetReference(); 989 990 if ((!parent.IsSet() && !socket->is_connected) || socket->peer.ss_len == 0) 991 return ENOTCONN; 992 993 memcpy(address, &socket->peer, min_c(*_addressLength, socket->peer.ss_len)); 994 *_addressLength = socket->peer.ss_len; 995 return B_OK; 996 } 997 998 999 int 1000 socket_getsockname(net_socket* socket, struct sockaddr* address, 1001 socklen_t* _addressLength) 1002 { 1003 if (socket->address.ss_len == 0) { 1004 struct sockaddr buffer; 1005 memset(&buffer, 0, sizeof(buffer)); 1006 buffer.sa_family = socket->family; 1007 1008 memcpy(address, &buffer, min_c(*_addressLength, sizeof(buffer))); 1009 *_addressLength = sizeof(buffer); 1010 return B_OK; 1011 } 1012 1013 memcpy(address, &socket->address, min_c(*_addressLength, 1014 socket->address.ss_len)); 1015 *_addressLength = socket->address.ss_len; 1016 return B_OK; 1017 } 1018 1019 1020 status_t 1021 socket_get_option(net_socket* socket, int level, int option, void* value, 1022 int* _length) 1023 { 1024 if (level != SOL_SOCKET) 1025 return ENOPROTOOPT; 1026 1027 switch (option) { 1028 case SO_SNDBUF: 1029 { 1030 uint32* size = (uint32*)value; 1031 *size = socket->send.buffer_size; 1032 *_length = sizeof(uint32); 1033 return B_OK; 1034 } 1035 1036 case SO_RCVBUF: 1037 { 1038 uint32* size = (uint32*)value; 1039 *size = socket->receive.buffer_size; 1040 *_length = sizeof(uint32); 1041 return B_OK; 1042 } 1043 1044 case SO_SNDLOWAT: 1045 { 1046 uint32* size = (uint32*)value; 1047 *size = socket->send.low_water_mark; 1048 *_length = sizeof(uint32); 1049 return B_OK; 1050 } 1051 1052 case SO_RCVLOWAT: 1053 { 1054 uint32* size = (uint32*)value; 1055 *size = socket->receive.low_water_mark; 1056 *_length = sizeof(uint32); 1057 return B_OK; 1058 } 1059 1060 case SO_RCVTIMEO: 1061 case SO_SNDTIMEO: 1062 { 1063 if (*_length < (int)sizeof(struct timeval)) 1064 return B_BAD_VALUE; 1065 1066 bigtime_t timeout; 1067 if (option == SO_SNDTIMEO) 1068 timeout = socket->send.timeout; 1069 else 1070 timeout = socket->receive.timeout; 1071 if (timeout == B_INFINITE_TIMEOUT) 1072 timeout = 0; 1073 1074 struct timeval* timeval = (struct timeval*)value; 1075 timeval->tv_sec = timeout / 1000000LL; 1076 timeval->tv_usec = timeout % 1000000LL; 1077 1078 *_length = sizeof(struct timeval); 1079 return B_OK; 1080 } 1081 1082 case SO_NONBLOCK: 1083 { 1084 int32* _set = (int32*)value; 1085 *_set = socket->receive.timeout == 0 && socket->send.timeout == 0; 1086 *_length = sizeof(int32); 1087 return B_OK; 1088 } 1089 1090 case SO_ACCEPTCONN: 1091 case SO_BROADCAST: 1092 case SO_DEBUG: 1093 case SO_DONTROUTE: 1094 case SO_KEEPALIVE: 1095 case SO_OOBINLINE: 1096 case SO_REUSEADDR: 1097 case SO_REUSEPORT: 1098 case SO_USELOOPBACK: 1099 { 1100 int32* _set = (int32*)value; 1101 *_set = (socket->options & option) != 0; 1102 *_length = sizeof(int32); 1103 return B_OK; 1104 } 1105 1106 case SO_TYPE: 1107 { 1108 int32* _set = (int32*)value; 1109 *_set = socket->type; 1110 *_length = sizeof(int32); 1111 return B_OK; 1112 } 1113 1114 case SO_ERROR: 1115 { 1116 int32* _set = (int32*)value; 1117 *_set = socket->error; 1118 *_length = sizeof(int32); 1119 1120 socket->error = B_OK; 1121 // clear error upon retrieval 1122 return B_OK; 1123 } 1124 1125 default: 1126 break; 1127 } 1128 1129 dprintf("socket_getsockopt: unknown option %d\n", option); 1130 return ENOPROTOOPT; 1131 } 1132 1133 1134 int 1135 socket_getsockopt(net_socket* socket, int level, int option, void* value, 1136 int* _length) 1137 { 1138 return socket->first_protocol->module->getsockopt(socket->first_protocol, 1139 level, option, value, _length); 1140 } 1141 1142 1143 int 1144 socket_listen(net_socket* socket, int backlog) 1145 { 1146 status_t status = socket->first_info->listen(socket->first_protocol, 1147 backlog); 1148 if (status == B_OK) 1149 socket->options |= SO_ACCEPTCONN; 1150 1151 return status; 1152 } 1153 1154 1155 ssize_t 1156 socket_receive(net_socket* socket, msghdr* header, void* data, size_t length, 1157 int flags) 1158 { 1159 const int originalFlags = flags; 1160 1161 // MSG_NOSIGNAL is only meaningful for send(), not receive(), but it is 1162 // sometimes specified anyway. Mask it off to avoid unnecessary errors. 1163 flags &= ~MSG_NOSIGNAL; 1164 1165 // If the protocol sports read_data_no_buffer() we use it. 1166 if (socket->first_info->read_data_no_buffer != NULL) 1167 return socket_receive_no_buffer(socket, header, data, length, flags); 1168 1169 // Mask off flags handled in this function. 1170 flags &= ~(MSG_TRUNC); 1171 1172 size_t totalLength = length; 1173 if (header != NULL) { 1174 ASSERT(data == header->msg_iov[0].iov_base); 1175 1176 // calculate the length considering all of the extra buffers 1177 for (int i = 1; i < header->msg_iovlen; i++) 1178 totalLength += header->msg_iov[i].iov_len; 1179 } 1180 1181 net_buffer* buffer; 1182 status_t status = socket->first_info->read_data( 1183 socket->first_protocol, totalLength, flags, &buffer); 1184 if (status != B_OK) 1185 return status; 1186 1187 // process ancillary data 1188 if (header != NULL) { 1189 if (buffer != NULL && header->msg_control != NULL) { 1190 ancillary_data_container* container 1191 = gNetBufferModule.get_ancillary_data(buffer); 1192 if (container != NULL) 1193 status = process_ancillary_data(socket, container, header); 1194 else 1195 status = process_ancillary_data(socket, buffer, header); 1196 if (status != B_OK) { 1197 gNetBufferModule.free(buffer); 1198 return status; 1199 } 1200 } else 1201 header->msg_controllen = 0; 1202 } 1203 1204 // TODO: - returning a NULL buffer when received 0 bytes 1205 // may not make much sense as we still need the address 1206 1207 size_t nameLen = 0; 1208 if (header != NULL) { 1209 // TODO: - consider the control buffer options 1210 nameLen = header->msg_namelen; 1211 header->msg_namelen = 0; 1212 header->msg_flags = 0; 1213 } 1214 1215 if (buffer == NULL) 1216 return 0; 1217 1218 const size_t bytesReceived = buffer->size; 1219 size_t bytesCopied = 0; 1220 1221 size_t toRead = min_c(bytesReceived, length); 1222 status = gNetBufferModule.read(buffer, 0, data, toRead); 1223 if (status != B_OK) { 1224 gNetBufferModule.free(buffer); 1225 1226 if (status == B_BAD_ADDRESS) 1227 return status; 1228 return ENOBUFS; 1229 } 1230 1231 // if first copy was a success, proceed to following copies as required 1232 bytesCopied += toRead; 1233 1234 if (header != NULL) { 1235 // We start at iovec[1] as { data, length } is iovec[0]. 1236 for (int i = 1; i < header->msg_iovlen && bytesCopied < bytesReceived; i++) { 1237 iovec& vec = header->msg_iov[i]; 1238 toRead = min_c(bytesReceived - bytesCopied, vec.iov_len); 1239 if (gNetBufferModule.read(buffer, bytesCopied, vec.iov_base, 1240 toRead) < B_OK) { 1241 break; 1242 } 1243 1244 bytesCopied += toRead; 1245 } 1246 1247 if (header->msg_name != NULL) { 1248 header->msg_namelen = min_c(nameLen, buffer->source->sa_len); 1249 memcpy(header->msg_name, buffer->source, header->msg_namelen); 1250 } 1251 } 1252 1253 gNetBufferModule.free(buffer); 1254 1255 if (bytesCopied < bytesReceived) { 1256 if (header != NULL) 1257 header->msg_flags = MSG_TRUNC; 1258 1259 if ((originalFlags & MSG_TRUNC) != 0) 1260 return bytesReceived; 1261 } 1262 1263 return bytesCopied; 1264 } 1265 1266 1267 ssize_t 1268 socket_send(net_socket* socket, msghdr* header, const void* data, size_t length, 1269 int flags) 1270 { 1271 const bool nosignal = ((flags & MSG_NOSIGNAL) != 0); 1272 flags &= ~MSG_NOSIGNAL; 1273 1274 size_t bytesLeft = length; 1275 if (length > SSIZE_MAX) 1276 return B_BAD_VALUE; 1277 1278 ancillary_data_container* ancillaryData = NULL; 1279 CObjectDeleter< 1280 ancillary_data_container, void, delete_ancillary_data_container> 1281 ancillaryDataDeleter; 1282 1283 const sockaddr* address = NULL; 1284 socklen_t addressLength = 0; 1285 if (header != NULL) { 1286 address = (const sockaddr*)header->msg_name; 1287 addressLength = header->msg_namelen; 1288 1289 // get the ancillary data 1290 if (header->msg_control != NULL) { 1291 ancillaryData = create_ancillary_data_container(); 1292 if (ancillaryData == NULL) 1293 return B_NO_MEMORY; 1294 ancillaryDataDeleter.SetTo(ancillaryData); 1295 1296 status_t status = add_ancillary_data(socket, ancillaryData, 1297 (cmsghdr*)header->msg_control, header->msg_controllen); 1298 if (status != B_OK) 1299 return status; 1300 } 1301 } 1302 1303 if (addressLength == 0) 1304 address = NULL; 1305 else if (address == NULL) 1306 return B_BAD_VALUE; 1307 1308 if (socket->peer.ss_len != 0) { 1309 if (address != NULL) 1310 return EISCONN; 1311 1312 // socket is connected, we use that address 1313 address = (struct sockaddr*)&socket->peer; 1314 addressLength = socket->peer.ss_len; 1315 } 1316 1317 if (address == NULL || addressLength == 0) { 1318 // don't know where to send to: 1319 return EDESTADDRREQ; 1320 } 1321 1322 if ((socket->first_info->flags & NET_PROTOCOL_ATOMIC_MESSAGES) != 0 1323 && bytesLeft > socket->send.buffer_size) 1324 return EMSGSIZE; 1325 1326 if (socket->address.ss_len == 0) { 1327 // try to bind first 1328 status_t status = socket_bind(socket, NULL, 0); 1329 if (status != B_OK) 1330 return status; 1331 } 1332 1333 // If the protocol has a send_data_no_buffer() hook, we use that one. 1334 if (socket->first_info->send_data_no_buffer != NULL) { 1335 iovec stackVec = { (void*)data, length }; 1336 iovec* vecs = header ? header->msg_iov : &stackVec; 1337 int vecCount = header ? header->msg_iovlen : 1; 1338 1339 ssize_t written = socket->first_info->send_data_no_buffer( 1340 socket->first_protocol, vecs, vecCount, ancillaryData, address, 1341 addressLength, flags); 1342 1343 // we only send signals when called from userland 1344 if (written == EPIPE && is_syscall() && !nosignal) 1345 send_signal(find_thread(NULL), SIGPIPE); 1346 1347 if (written > 0) 1348 ancillaryDataDeleter.Detach(); 1349 return written; 1350 } 1351 1352 // By convention, if a header is given, the (data, length) equals the first 1353 // iovec. So drop the header, if it is the only iovec. Otherwise compute 1354 // the size of the remaining ones. 1355 if (header != NULL) { 1356 if (header->msg_iovlen <= 1) { 1357 header = NULL; 1358 } else { 1359 for (int i = 1; i < header->msg_iovlen; i++) 1360 bytesLeft += header->msg_iov[i].iov_len; 1361 } 1362 } 1363 1364 ssize_t bytesSent = 0; 1365 size_t vecOffset = 0; 1366 uint32 vecIndex = 0; 1367 1368 while (bytesLeft > 0) { 1369 // TODO: useful, maybe even computed header space! 1370 net_buffer* buffer = gNetBufferModule.create(256); 1371 if (buffer == NULL) 1372 return ENOBUFS; 1373 1374 while (buffer->size < socket->send.buffer_size 1375 && buffer->size < bytesLeft) { 1376 if (vecIndex > 0 && vecOffset == 0) { 1377 // retrieve next iovec buffer from header 1378 data = header->msg_iov[vecIndex].iov_base; 1379 length = header->msg_iov[vecIndex].iov_len; 1380 } 1381 1382 size_t bytes = length; 1383 if (buffer->size + bytes > socket->send.buffer_size) 1384 bytes = socket->send.buffer_size - buffer->size; 1385 1386 if (gNetBufferModule.append(buffer, data, bytes) < B_OK) { 1387 gNetBufferModule.free(buffer); 1388 return ENOBUFS; 1389 } 1390 1391 if (bytes != length) { 1392 // partial send 1393 vecOffset = bytes; 1394 length -= vecOffset; 1395 data = (uint8*)data + vecOffset; 1396 } else if (header != NULL) { 1397 // proceed with next buffer, if any 1398 vecOffset = 0; 1399 vecIndex++; 1400 1401 if (vecIndex >= (uint32)header->msg_iovlen) 1402 break; 1403 } 1404 } 1405 1406 // attach ancillary data to the first buffer 1407 status_t status; 1408 if (ancillaryData != NULL) { 1409 gNetBufferModule.set_ancillary_data(buffer, ancillaryData); 1410 ancillaryDataDeleter.Detach(); 1411 ancillaryData = NULL; 1412 } 1413 1414 size_t bufferSize = buffer->size; 1415 buffer->flags = flags; 1416 memcpy(buffer->source, &socket->address, socket->address.ss_len); 1417 memcpy(buffer->destination, address, addressLength); 1418 buffer->destination->sa_len = addressLength; 1419 1420 status = socket->first_info->send_data(socket->first_protocol, buffer); 1421 if (status != B_OK) { 1422 // we only send signals when called from userland 1423 if (status == EPIPE && is_syscall() && !nosignal) 1424 send_signal(find_thread(NULL), SIGPIPE); 1425 1426 size_t sizeAfterSend = buffer->size; 1427 gNetBufferModule.free(buffer); 1428 1429 if ((sizeAfterSend != bufferSize || bytesSent > 0) 1430 && (status == B_INTERRUPTED || status == B_WOULD_BLOCK)) { 1431 // this appears to be a partial write 1432 return bytesSent + (bufferSize - sizeAfterSend); 1433 } 1434 return status; 1435 } 1436 1437 bytesLeft -= bufferSize; 1438 bytesSent += bufferSize; 1439 } 1440 1441 return bytesSent; 1442 } 1443 1444 1445 status_t 1446 socket_set_option(net_socket* socket, int level, int option, const void* value, 1447 int length) 1448 { 1449 if (level != SOL_SOCKET) 1450 return ENOPROTOOPT; 1451 1452 TRACE("%s(socket %p, option %d\n", __FUNCTION__, socket, option); 1453 1454 switch (option) { 1455 // TODO: implement other options! 1456 case SO_LINGER: 1457 { 1458 if (length < (int)sizeof(struct linger)) 1459 return B_BAD_VALUE; 1460 1461 struct linger* linger = (struct linger*)value; 1462 if (linger->l_onoff) { 1463 socket->options |= SO_LINGER; 1464 socket->linger = linger->l_linger; 1465 } else { 1466 socket->options &= ~SO_LINGER; 1467 socket->linger = 0; 1468 } 1469 return B_OK; 1470 } 1471 1472 case SO_SNDBUF: 1473 if (length != sizeof(uint32)) 1474 return B_BAD_VALUE; 1475 1476 socket->send.buffer_size = *(const uint32*)value; 1477 return B_OK; 1478 1479 case SO_RCVBUF: 1480 if (length != sizeof(uint32)) 1481 return B_BAD_VALUE; 1482 1483 socket->receive.buffer_size = *(const uint32*)value; 1484 return B_OK; 1485 1486 case SO_SNDLOWAT: 1487 if (length != sizeof(uint32)) 1488 return B_BAD_VALUE; 1489 1490 socket->send.low_water_mark = *(const uint32*)value; 1491 return B_OK; 1492 1493 case SO_RCVLOWAT: 1494 if (length != sizeof(uint32)) 1495 return B_BAD_VALUE; 1496 1497 socket->receive.low_water_mark = *(const uint32*)value; 1498 return B_OK; 1499 1500 case SO_RCVTIMEO: 1501 case SO_SNDTIMEO: 1502 { 1503 if (length != sizeof(struct timeval)) 1504 return B_BAD_VALUE; 1505 1506 const struct timeval* timeval = (const struct timeval*)value; 1507 bigtime_t timeout = timeval->tv_sec * 1000000LL + timeval->tv_usec; 1508 if (timeout == 0) 1509 timeout = B_INFINITE_TIMEOUT; 1510 1511 if (option == SO_SNDTIMEO) 1512 socket->send.timeout = timeout; 1513 else 1514 socket->receive.timeout = timeout; 1515 return B_OK; 1516 } 1517 1518 case SO_NONBLOCK: 1519 if (length != sizeof(int32)) 1520 return B_BAD_VALUE; 1521 1522 if (*(const int32*)value) { 1523 socket->send.timeout = 0; 1524 socket->receive.timeout = 0; 1525 } else { 1526 socket->send.timeout = B_INFINITE_TIMEOUT; 1527 socket->receive.timeout = B_INFINITE_TIMEOUT; 1528 } 1529 return B_OK; 1530 1531 case SO_BROADCAST: 1532 case SO_DEBUG: 1533 case SO_DONTROUTE: 1534 case SO_KEEPALIVE: 1535 case SO_OOBINLINE: 1536 case SO_REUSEADDR: 1537 case SO_REUSEPORT: 1538 case SO_USELOOPBACK: 1539 if (length != sizeof(int32)) 1540 return B_BAD_VALUE; 1541 1542 if (*(const int32*)value) 1543 socket->options |= option; 1544 else 1545 socket->options &= ~option; 1546 return B_OK; 1547 1548 case SO_BINDTODEVICE: 1549 { 1550 if (length != sizeof(uint32)) 1551 return B_BAD_VALUE; 1552 1553 // TODO: we might want to check if the device exists at all 1554 // (although it doesn't really harm when we don't) 1555 socket->bound_to_device = *(const uint32*)value; 1556 return B_OK; 1557 } 1558 1559 default: 1560 break; 1561 } 1562 1563 dprintf("socket_setsockopt: unknown option %d\n", option); 1564 return ENOPROTOOPT; 1565 } 1566 1567 1568 int 1569 socket_setsockopt(net_socket* socket, int level, int option, const void* value, 1570 int length) 1571 { 1572 return socket->first_protocol->module->setsockopt(socket->first_protocol, 1573 level, option, value, length); 1574 } 1575 1576 1577 int 1578 socket_shutdown(net_socket* socket, int direction) 1579 { 1580 return socket->first_info->shutdown(socket->first_protocol, direction); 1581 } 1582 1583 1584 status_t 1585 socket_socketpair(int family, int type, int protocol, net_socket* sockets[2]) 1586 { 1587 sockets[0] = NULL; 1588 sockets[1] = NULL; 1589 1590 // create sockets 1591 status_t error = socket_open(family, type, protocol, &sockets[0]); 1592 if (error != B_OK) 1593 return error; 1594 1595 error = socket_open(family, type, protocol, &sockets[1]); 1596 1597 // bind one 1598 if (error == B_OK) 1599 error = socket_bind(sockets[0], NULL, 0); 1600 1601 // start listening 1602 if (error == B_OK && type == SOCK_STREAM) 1603 error = socket_listen(sockets[0], 1); 1604 1605 // connect them 1606 if (error == B_OK) { 1607 error = socket_connect(sockets[1], (sockaddr*)&sockets[0]->address, 1608 sockets[0]->address.ss_len); 1609 } 1610 1611 if (error == B_OK) { 1612 // accept a socket 1613 if (type == SOCK_STREAM) { 1614 net_socket* acceptedSocket = NULL; 1615 error = socket_accept(sockets[0], NULL, NULL, &acceptedSocket); 1616 if (error == B_OK) { 1617 // everything worked: close the listener socket 1618 socket_close(sockets[0]); 1619 socket_free(sockets[0]); 1620 sockets[0] = acceptedSocket; 1621 } 1622 // connect the other side 1623 } else { 1624 error = socket_connect(sockets[0], (sockaddr*)&sockets[1]->address, 1625 sockets[1]->address.ss_len); 1626 } 1627 } 1628 1629 if (error != B_OK) { 1630 // close sockets on error 1631 for (int i = 0; i < 2; i++) { 1632 if (sockets[i] != NULL) { 1633 socket_close(sockets[i]); 1634 socket_free(sockets[i]); 1635 sockets[i] = NULL; 1636 } 1637 } 1638 } 1639 1640 return error; 1641 } 1642 1643 1644 // #pragma mark - 1645 1646 1647 static status_t 1648 socket_std_ops(int32 op, ...) 1649 { 1650 switch (op) { 1651 case B_MODULE_INIT: 1652 { 1653 new (&sSocketList) SocketList; 1654 mutex_init(&sSocketLock, "socket list"); 1655 1656 #if ENABLE_DEBUGGER_COMMANDS 1657 add_debugger_command("sockets", dump_sockets, "lists all sockets"); 1658 add_debugger_command("socket", dump_socket, "dumps a socket"); 1659 #endif 1660 return B_OK; 1661 } 1662 case B_MODULE_UNINIT: 1663 ASSERT(sSocketList.IsEmpty()); 1664 mutex_destroy(&sSocketLock); 1665 1666 #if ENABLE_DEBUGGER_COMMANDS 1667 remove_debugger_command("socket", dump_socket); 1668 remove_debugger_command("sockets", dump_sockets); 1669 #endif 1670 return B_OK; 1671 1672 default: 1673 return B_ERROR; 1674 } 1675 } 1676 1677 1678 net_socket_module_info gNetSocketModule = { 1679 { 1680 NET_SOCKET_MODULE_NAME, 1681 0, 1682 socket_std_ops 1683 }, 1684 socket_open, 1685 socket_close, 1686 socket_free, 1687 1688 socket_control, 1689 1690 socket_read_avail, 1691 socket_send_avail, 1692 1693 socket_send_data, 1694 socket_receive_data, 1695 1696 socket_get_option, 1697 socket_set_option, 1698 1699 socket_get_next_stat, 1700 1701 // connections 1702 socket_acquire, 1703 socket_release, 1704 socket_spawn_pending, 1705 socket_dequeue_connected, 1706 socket_count_connected, 1707 socket_set_max_backlog, 1708 socket_has_parent, 1709 socket_connected, 1710 socket_aborted, 1711 1712 // notifications 1713 socket_request_notification, 1714 socket_cancel_notification, 1715 socket_notify, 1716 1717 // standard socket API 1718 socket_accept, 1719 socket_bind, 1720 socket_connect, 1721 socket_getpeername, 1722 socket_getsockname, 1723 socket_getsockopt, 1724 socket_listen, 1725 socket_receive, 1726 socket_send, 1727 socket_setsockopt, 1728 socket_shutdown, 1729 socket_socketpair 1730 }; 1731 1732