1 /* 2 * Copyright 2006-2021, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Oliver Tappe, zooey@hirschkaefer.de 7 * Hugo Santos, hugosantos@gmail.com 8 */ 9 10 11 #include <net_buffer.h> 12 #include <net_datalink.h> 13 #include <net_protocol.h> 14 #include <net_stack.h> 15 16 #include <lock.h> 17 #include <util/AutoLock.h> 18 #include <util/DoublyLinkedList.h> 19 #include <util/OpenHashTable.h> 20 21 #include <AutoDeleter.h> 22 #include <KernelExport.h> 23 24 #include <NetBufferUtilities.h> 25 #include <NetUtilities.h> 26 #include <ProtocolUtilities.h> 27 28 #include <algorithm> 29 #include <netinet/in.h> 30 #include <netinet/ip.h> 31 #include <new> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <utility> 35 36 37 // NOTE the locking protocol dictates that we must hold UdpDomainSupport's 38 // lock before holding a child UdpEndpoint's lock. This restriction 39 // is dictated by the receive path as blind access to the endpoint 40 // hash is required when holding the DomainSupport's lock. 41 42 43 //#define TRACE_UDP 44 #ifdef TRACE_UDP 45 # define TRACE_BLOCK(x) dump_block x 46 // do not remove the space before ', ##args' if you want this 47 // to compile with gcc 2.95 48 # define TRACE_EP(format, args...) dprintf("UDP [%" B_PRIu64 ",%" \ 49 B_PRIu32 "] %p " format "\n", system_time(), \ 50 thread_get_current_thread_id(), this , ##args) 51 # define TRACE_EPM(format, args...) dprintf("UDP [%" B_PRIu64 ",%" \ 52 B_PRIu32 "] " format "\n", system_time() , \ 53 thread_get_current_thread_id() , ##args) 54 # define TRACE_DOMAIN(format, args...) dprintf("UDP [%" B_PRIu64 ",%" \ 55 B_PRIu32 "] (%d) " format "\n", system_time(), \ 56 thread_get_current_thread_id(), Domain()->family , ##args) 57 #else 58 # define TRACE_BLOCK(x) 59 # define TRACE_EP(args...) do { } while (0) 60 # define TRACE_EPM(args...) do { } while (0) 61 # define TRACE_DOMAIN(args...) do { } while (0) 62 #endif 63 64 65 struct udp_header { 66 uint16 source_port; 67 uint16 destination_port; 68 uint16 udp_length; 69 uint16 udp_checksum; 70 } _PACKED; 71 72 73 typedef NetBufferField<uint16, offsetof(udp_header, udp_checksum)> 74 UDPChecksumField; 75 76 class UdpDomainSupport; 77 78 class UdpEndpoint : public net_protocol, public DatagramSocket<> { 79 public: 80 UdpEndpoint(net_socket* socket); 81 82 status_t Bind(const sockaddr* newAddr); 83 status_t Unbind(sockaddr* newAddr); 84 status_t Connect(const sockaddr* newAddr); 85 86 status_t Open(); 87 status_t Close(); 88 status_t Free(); 89 90 status_t SendRoutedData(net_buffer* buffer, 91 net_route* route); 92 status_t SendData(net_buffer* buffer); 93 94 ssize_t BytesAvailable(); 95 status_t FetchData(size_t numBytes, uint32 flags, 96 net_buffer** _buffer); 97 98 status_t StoreData(net_buffer* buffer); 99 status_t DeliverData(net_buffer* buffer); 100 101 // only the domain support will change/check the Active flag so 102 // we don't really need to protect it with the socket lock. 103 bool IsActive() const { return fActive; } 104 void SetActive(bool newValue) { fActive = newValue; } 105 106 UdpEndpoint*& HashTableLink() { return fLink; } 107 108 void Dump() const; 109 110 private: 111 UdpDomainSupport* fManager; 112 bool fActive; 113 // an active UdpEndpoint is part of the 114 // endpoint hash (and it is bound and 115 // optionally connected) 116 117 UdpEndpoint* fLink; 118 }; 119 120 121 class UdpDomainSupport; 122 123 struct UdpHashDefinition { 124 typedef net_address_module_info ParentType; 125 typedef std::pair<const sockaddr *, const sockaddr *> KeyType; 126 typedef UdpEndpoint ValueType; 127 128 UdpHashDefinition(net_address_module_info *_module) 129 : module(_module) {} 130 UdpHashDefinition(const UdpHashDefinition& definition) 131 : module(definition.module) {} 132 133 size_t HashKey(const KeyType &key) const 134 { 135 return _Mix(module->hash_address_pair(key.first, key.second)); 136 } 137 138 size_t Hash(UdpEndpoint *endpoint) const 139 { 140 return _Mix(endpoint->LocalAddress().HashPair( 141 *endpoint->PeerAddress())); 142 } 143 144 static size_t _Mix(size_t hash) 145 { 146 // move the bits into the relevant range (as defined by kNumHashBuckets) 147 return (hash & 0x000007FF) ^ (hash & 0x003FF800) >> 11 148 ^ (hash & 0xFFC00000UL) >> 22; 149 } 150 151 bool Compare(const KeyType &key, UdpEndpoint *endpoint) const 152 { 153 return endpoint->LocalAddress().EqualTo(key.first, true) 154 && endpoint->PeerAddress().EqualTo(key.second, true); 155 } 156 157 UdpEndpoint *&GetLink(UdpEndpoint *endpoint) const 158 { 159 return endpoint->HashTableLink(); 160 } 161 162 net_address_module_info *module; 163 }; 164 165 166 class UdpDomainSupport : public DoublyLinkedListLinkImpl<UdpDomainSupport> { 167 public: 168 UdpDomainSupport(net_domain *domain); 169 ~UdpDomainSupport(); 170 171 status_t Init(); 172 173 net_domain *Domain() const { return fDomain; } 174 175 void Ref() { fEndpointCount++; } 176 bool Put() { fEndpointCount--; return fEndpointCount == 0; } 177 178 status_t DemuxIncomingBuffer(net_buffer* buffer); 179 status_t DeliverError(status_t error, net_buffer* buffer); 180 181 status_t BindEndpoint(UdpEndpoint *endpoint, const sockaddr *address); 182 status_t ConnectEndpoint(UdpEndpoint *endpoint, const sockaddr *address); 183 status_t UnbindEndpoint(UdpEndpoint *endpoint); 184 185 void DumpEndpoints() const; 186 187 private: 188 status_t _BindEndpoint(UdpEndpoint *endpoint, const sockaddr *address); 189 status_t _Bind(UdpEndpoint *endpoint, const sockaddr *address); 190 status_t _BindToEphemeral(UdpEndpoint *endpoint, const sockaddr *address); 191 status_t _FinishBind(UdpEndpoint *endpoint, const sockaddr *address); 192 193 UdpEndpoint *_FindActiveEndpoint(const sockaddr *ourAddress, 194 const sockaddr *peerAddress, uint32 index = 0); 195 status_t _DemuxBroadcast(net_buffer *buffer); 196 status_t _DemuxUnicast(net_buffer *buffer); 197 198 uint16 _GetNextEphemeral(); 199 UdpEndpoint *_EndpointWithPort(uint16 port) const; 200 201 net_address_module_info *AddressModule() const 202 { return fDomain->address_module; } 203 204 typedef BOpenHashTable<UdpHashDefinition, false> EndpointTable; 205 206 mutex fLock; 207 net_domain *fDomain; 208 uint16 fLastUsedEphemeral; 209 EndpointTable fActiveEndpoints; 210 uint32 fEndpointCount; 211 212 static const uint16 kFirst = 49152; 213 static const uint16 kLast = 65535; 214 static const uint32 kNumHashBuckets = 0x800; 215 // if you change this, adjust the shifting in 216 // Hash() accordingly! 217 }; 218 219 220 typedef DoublyLinkedList<UdpDomainSupport> UdpDomainList; 221 222 223 class UdpEndpointManager { 224 public: 225 UdpEndpointManager(); 226 ~UdpEndpointManager(); 227 228 status_t InitCheck() const; 229 230 status_t ReceiveData(net_buffer* buffer); 231 status_t ReceiveError(status_t error, 232 net_buffer* buffer); 233 status_t Deframe(net_buffer* buffer); 234 235 UdpDomainSupport* OpenEndpoint(UdpEndpoint* endpoint); 236 status_t FreeEndpoint(UdpDomainSupport* domain); 237 238 static int DumpEndpoints(int argc, char *argv[]); 239 240 private: 241 inline net_domain* _GetDomain(net_buffer* buffer); 242 UdpDomainSupport* _GetDomainSupport(net_domain* domain, 243 bool create); 244 UdpDomainSupport* _GetDomainSupport(net_buffer* buffer); 245 246 mutex fLock; 247 status_t fStatus; 248 UdpDomainList fDomains; 249 }; 250 251 252 static UdpEndpointManager *sUdpEndpointManager; 253 254 net_buffer_module_info *gBufferModule; 255 net_datalink_module_info *gDatalinkModule; 256 net_stack_module_info *gStackModule; 257 net_socket_module_info *gSocketModule; 258 259 260 // #pragma mark - 261 262 263 UdpDomainSupport::UdpDomainSupport(net_domain *domain) 264 : 265 fDomain(domain), 266 fActiveEndpoints(domain->address_module), 267 fEndpointCount(0) 268 { 269 mutex_init(&fLock, "udp domain"); 270 271 fLastUsedEphemeral = kFirst + rand() % (kLast - kFirst); 272 } 273 274 275 UdpDomainSupport::~UdpDomainSupport() 276 { 277 mutex_destroy(&fLock); 278 } 279 280 281 status_t 282 UdpDomainSupport::Init() 283 { 284 return fActiveEndpoints.Init(kNumHashBuckets); 285 } 286 287 288 status_t 289 UdpDomainSupport::DemuxIncomingBuffer(net_buffer *buffer) 290 { 291 // NOTE: multicast is delivered directly to the endpoint 292 MutexLocker _(fLock); 293 294 if ((buffer->msg_flags & MSG_BCAST) != 0) 295 return _DemuxBroadcast(buffer); 296 if ((buffer->msg_flags & MSG_MCAST) != 0) 297 return B_ERROR; 298 299 return _DemuxUnicast(buffer); 300 } 301 302 303 status_t 304 UdpDomainSupport::DeliverError(status_t error, net_buffer* buffer) 305 { 306 if ((buffer->msg_flags & (MSG_BCAST | MSG_MCAST)) != 0) 307 return B_ERROR; 308 309 MutexLocker _(fLock); 310 311 // Forward the error to the socket 312 UdpEndpoint* endpoint = _FindActiveEndpoint(buffer->source, 313 buffer->destination); 314 if (endpoint != NULL) { 315 gSocketModule->notify(endpoint->Socket(), B_SELECT_ERROR, error); 316 endpoint->NotifyOne(); 317 } 318 319 gBufferModule->free(buffer); 320 return B_OK; 321 } 322 323 324 status_t 325 UdpDomainSupport::BindEndpoint(UdpEndpoint *endpoint, 326 const sockaddr *address) 327 { 328 if (!AddressModule()->is_same_family(address)) 329 return EAFNOSUPPORT; 330 331 MutexLocker _(fLock); 332 333 if (endpoint->IsActive()) 334 return EINVAL; 335 336 return _BindEndpoint(endpoint, address); 337 } 338 339 340 status_t 341 UdpDomainSupport::ConnectEndpoint(UdpEndpoint *endpoint, 342 const sockaddr *address) 343 { 344 MutexLocker _(fLock); 345 346 if (endpoint->IsActive()) { 347 fActiveEndpoints.Remove(endpoint); 348 endpoint->SetActive(false); 349 } 350 351 if (address->sa_family == AF_UNSPEC) { 352 // [Stevens-UNP1, p226]: specifying AF_UNSPEC requests a "disconnect", 353 // so we reset the peer address: 354 endpoint->PeerAddress().SetToEmpty(); 355 } else { 356 if (!AddressModule()->is_same_family(address)) 357 return EAFNOSUPPORT; 358 359 // consider destination address INADDR_ANY as INADDR_LOOPBACK 360 sockaddr_storage _address; 361 if (AddressModule()->is_empty_address(address, false)) { 362 AddressModule()->get_loopback_address((sockaddr *)&_address); 363 // for IPv4 and IPv6 the port is at the same offset 364 ((sockaddr_in&)_address).sin_port 365 = ((sockaddr_in *)address)->sin_port; 366 address = (sockaddr *)&_address; 367 } 368 369 status_t status = endpoint->PeerAddress().SetTo(address); 370 if (status < B_OK) 371 return status; 372 struct net_route *routeToDestination 373 = gDatalinkModule->get_route(fDomain, address); 374 if (routeToDestination) { 375 // stay bound to current local port, if any. 376 uint16 port = endpoint->LocalAddress().Port(); 377 status = endpoint->LocalAddress().SetTo( 378 routeToDestination->interface_address->local); 379 endpoint->LocalAddress().SetPort(port); 380 gDatalinkModule->put_route(fDomain, routeToDestination); 381 if (status < B_OK) 382 return status; 383 } 384 } 385 386 // we need to activate no matter whether or not we have just disconnected, 387 // as calling connect() always triggers an implicit bind(): 388 status_t status = _BindEndpoint(endpoint, *endpoint->LocalAddress()); 389 if (status == B_OK) 390 gSocketModule->set_connected(endpoint->Socket()); 391 return status; 392 } 393 394 395 status_t 396 UdpDomainSupport::UnbindEndpoint(UdpEndpoint *endpoint) 397 { 398 MutexLocker _(fLock); 399 400 if (endpoint->IsActive()) 401 fActiveEndpoints.Remove(endpoint); 402 403 endpoint->SetActive(false); 404 405 return B_OK; 406 } 407 408 409 void 410 UdpDomainSupport::DumpEndpoints() const 411 { 412 kprintf("-------- UDP Domain %p ---------\n", this); 413 kprintf("%10s %20s %20s %8s\n", "address", "local", "peer", "recv-q"); 414 415 EndpointTable::Iterator it = fActiveEndpoints.GetIterator(); 416 417 while (UdpEndpoint* endpoint = it.Next()) { 418 endpoint->Dump(); 419 } 420 } 421 422 423 status_t 424 UdpDomainSupport::_BindEndpoint(UdpEndpoint *endpoint, 425 const sockaddr *address) 426 { 427 if (AddressModule()->get_port(address) == 0) 428 return _BindToEphemeral(endpoint, address); 429 430 return _Bind(endpoint, address); 431 } 432 433 434 status_t 435 UdpDomainSupport::_Bind(UdpEndpoint *endpoint, const sockaddr *address) 436 { 437 int socketOptions = endpoint->Socket()->options; 438 439 EndpointTable::Iterator it = fActiveEndpoints.GetIterator(); 440 441 // Iterate over all active UDP-endpoints and check if the requested bind 442 // is allowed (see figure 22.24 in [Stevens - TCP2, p735]): 443 TRACE_DOMAIN("CheckBindRequest() for %s...", AddressString(fDomain, 444 address, true).Data()); 445 446 while (it.HasNext()) { 447 UdpEndpoint *otherEndpoint = it.Next(); 448 449 TRACE_DOMAIN(" ...checking endpoint %p (port=%u)...", otherEndpoint, 450 ntohs(otherEndpoint->LocalAddress().Port())); 451 452 if (otherEndpoint->LocalAddress().EqualPorts(address)) { 453 // port is already bound, SO_REUSEADDR or SO_REUSEPORT is required: 454 if ((otherEndpoint->Socket()->options 455 & (SO_REUSEADDR | SO_REUSEPORT)) == 0 456 || (socketOptions & (SO_REUSEADDR | SO_REUSEPORT)) == 0) 457 return EADDRINUSE; 458 459 // if both addresses are the same, SO_REUSEPORT is required: 460 if (otherEndpoint->LocalAddress().EqualTo(address, false) 461 && ((otherEndpoint->Socket()->options & SO_REUSEPORT) == 0 462 || (socketOptions & SO_REUSEPORT) == 0)) 463 return EADDRINUSE; 464 } 465 } 466 467 return _FinishBind(endpoint, address); 468 } 469 470 471 status_t 472 UdpDomainSupport::_BindToEphemeral(UdpEndpoint *endpoint, 473 const sockaddr *address) 474 { 475 SocketAddressStorage newAddress(AddressModule()); 476 status_t status = newAddress.SetTo(address); 477 if (status < B_OK) 478 return status; 479 480 uint16 allocedPort = _GetNextEphemeral(); 481 if (allocedPort == 0) 482 return ENOBUFS; 483 484 newAddress.SetPort(htons(allocedPort)); 485 486 return _FinishBind(endpoint, *newAddress); 487 } 488 489 490 status_t 491 UdpDomainSupport::_FinishBind(UdpEndpoint *endpoint, const sockaddr *address) 492 { 493 status_t status = endpoint->next->module->bind(endpoint->next, address); 494 if (status < B_OK) 495 return status; 496 497 fActiveEndpoints.Insert(endpoint); 498 endpoint->SetActive(true); 499 500 return B_OK; 501 } 502 503 504 UdpEndpoint * 505 UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress, 506 const sockaddr *peerAddress, uint32 index) 507 { 508 ASSERT_LOCKED_MUTEX(&fLock); 509 510 TRACE_DOMAIN("finding Endpoint for %s <- %s", 511 AddressString(fDomain, ourAddress, true).Data(), 512 AddressString(fDomain, peerAddress, true).Data()); 513 514 UdpEndpoint* endpoint = fActiveEndpoints.Lookup( 515 std::make_pair(ourAddress, peerAddress)); 516 517 // Make sure the bound_to_device constraint is fulfilled 518 while (endpoint != NULL && endpoint->socket->bound_to_device != 0 519 && index != 0 && endpoint->socket->bound_to_device != index) { 520 endpoint = endpoint->HashTableLink(); 521 if (endpoint != NULL 522 && (!endpoint->LocalAddress().EqualTo(ourAddress, true) 523 || !endpoint->PeerAddress().EqualTo(peerAddress, true))) 524 return NULL; 525 } 526 527 return endpoint; 528 } 529 530 531 status_t 532 UdpDomainSupport::_DemuxBroadcast(net_buffer* buffer) 533 { 534 sockaddr* peerAddr = buffer->source; 535 sockaddr* broadcastAddr = buffer->destination; 536 uint16 incomingPort = AddressModule()->get_port(broadcastAddr); 537 538 sockaddr* mask = NULL; 539 if (buffer->interface_address != NULL) 540 mask = (sockaddr*)buffer->interface_address->mask; 541 542 TRACE_DOMAIN("_DemuxBroadcast(%p): mask %p\n", buffer, mask); 543 544 EndpointTable::Iterator iterator = fActiveEndpoints.GetIterator(); 545 546 while (UdpEndpoint* endpoint = iterator.Next()) { 547 TRACE_DOMAIN(" _DemuxBroadcast(): checking endpoint %s...", 548 AddressString(fDomain, *endpoint->LocalAddress(), true).Data()); 549 550 if (endpoint->socket->bound_to_device != 0 551 && buffer->index != endpoint->socket->bound_to_device) 552 continue; 553 554 if (endpoint->LocalAddress().Port() != incomingPort) { 555 // ports don't match, so we do not dispatch to this endpoint... 556 continue; 557 } 558 559 if (!endpoint->PeerAddress().IsEmpty(true)) { 560 // endpoint is connected to a specific destination, we check if 561 // this datagram is from there: 562 if (!endpoint->PeerAddress().EqualTo(peerAddr, true)) { 563 // no, datagram is from another peer, so we do not dispatch to 564 // this endpoint... 565 continue; 566 } 567 } 568 569 if (endpoint->LocalAddress().MatchMasked(broadcastAddr, mask) 570 || mask == NULL || endpoint->LocalAddress().IsEmpty(false)) { 571 // address matches, dispatch to this endpoint: 572 endpoint->StoreData(buffer); 573 } 574 } 575 576 return B_OK; 577 } 578 579 580 status_t 581 UdpDomainSupport::_DemuxUnicast(net_buffer* buffer) 582 { 583 TRACE_DOMAIN("_DemuxUnicast(%p)", buffer); 584 585 const sockaddr* localAddress = buffer->destination; 586 const sockaddr* peerAddress = buffer->source; 587 588 // look for full (most special) match: 589 UdpEndpoint* endpoint = _FindActiveEndpoint(localAddress, peerAddress, 590 buffer->index); 591 if (endpoint == NULL) { 592 // look for endpoint matching local address & port: 593 endpoint = _FindActiveEndpoint(localAddress, NULL, buffer->index); 594 if (endpoint == NULL) { 595 // look for endpoint matching peer address & port and local port: 596 SocketAddressStorage local(AddressModule()); 597 local.SetToEmpty(); 598 local.SetPort(AddressModule()->get_port(localAddress)); 599 endpoint = _FindActiveEndpoint(*local, peerAddress, buffer->index); 600 if (endpoint == NULL) { 601 // last chance: look for endpoint matching local port only: 602 endpoint = _FindActiveEndpoint(*local, NULL, buffer->index); 603 } 604 } 605 } 606 607 if (endpoint == NULL) { 608 TRACE_DOMAIN("_DemuxUnicast(%p) - no matching endpoint found!", buffer); 609 return B_NAME_NOT_FOUND; 610 } 611 612 endpoint->StoreData(buffer); 613 return B_OK; 614 } 615 616 617 uint16 618 UdpDomainSupport::_GetNextEphemeral() 619 { 620 uint16 stop, curr; 621 if (fLastUsedEphemeral < kLast) { 622 stop = fLastUsedEphemeral; 623 curr = fLastUsedEphemeral + 1; 624 } else { 625 stop = kLast; 626 curr = kFirst; 627 } 628 629 TRACE_DOMAIN("_GetNextEphemeral(), last %hu, curr %hu, stop %hu", 630 fLastUsedEphemeral, curr, stop); 631 632 // TODO: a free list could be used to avoid the impact of these two 633 // nested loops most of the time... let's see how bad this really is 634 for (; curr != stop; curr = (curr < kLast) ? (curr + 1) : kFirst) { 635 TRACE_DOMAIN(" _GetNextEphemeral(): trying port %hu...", curr); 636 637 if (_EndpointWithPort(htons(curr)) == NULL) { 638 TRACE_DOMAIN(" _GetNextEphemeral(): ...using port %hu", curr); 639 fLastUsedEphemeral = curr; 640 return curr; 641 } 642 } 643 644 return 0; 645 } 646 647 648 UdpEndpoint * 649 UdpDomainSupport::_EndpointWithPort(uint16 port) const 650 { 651 EndpointTable::Iterator it = fActiveEndpoints.GetIterator(); 652 653 while (it.HasNext()) { 654 UdpEndpoint *endpoint = it.Next(); 655 if (endpoint->LocalAddress().Port() == port) 656 return endpoint; 657 } 658 659 return NULL; 660 } 661 662 663 // #pragma mark - 664 665 666 UdpEndpointManager::UdpEndpointManager() 667 { 668 mutex_init(&fLock, "UDP endpoints"); 669 fStatus = B_OK; 670 } 671 672 673 UdpEndpointManager::~UdpEndpointManager() 674 { 675 mutex_destroy(&fLock); 676 } 677 678 679 status_t 680 UdpEndpointManager::InitCheck() const 681 { 682 return fStatus; 683 } 684 685 686 int 687 UdpEndpointManager::DumpEndpoints(int argc, char *argv[]) 688 { 689 UdpDomainList::Iterator it = sUdpEndpointManager->fDomains.GetIterator(); 690 691 kprintf("===== UDP domain manager %p =====\n", sUdpEndpointManager); 692 693 while (it.HasNext()) 694 it.Next()->DumpEndpoints(); 695 696 return 0; 697 } 698 699 700 // #pragma mark - inbound 701 702 703 struct DomainSupportDelete 704 { 705 inline void operator()(UdpDomainSupport* object) 706 { 707 sUdpEndpointManager->FreeEndpoint(object); 708 } 709 }; 710 711 712 struct DomainSupportDeleter 713 : BPrivate::AutoDeleter<UdpDomainSupport, DomainSupportDelete> 714 { 715 DomainSupportDeleter(UdpDomainSupport* object) 716 : BPrivate::AutoDeleter<UdpDomainSupport, DomainSupportDelete>(object) 717 {} 718 }; 719 720 721 status_t 722 UdpEndpointManager::ReceiveData(net_buffer *buffer) 723 { 724 TRACE_EPM("ReceiveData(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 725 726 UdpDomainSupport* domainSupport = _GetDomainSupport(buffer); 727 if (domainSupport == NULL) { 728 // we don't instantiate domain supports in the receiving path, as 729 // we are only interested in delivering data to existing sockets. 730 return B_ERROR; 731 } 732 DomainSupportDeleter deleter(domainSupport); 733 734 status_t status = Deframe(buffer); 735 if (status != B_OK) { 736 return status; 737 } 738 739 status = domainSupport->DemuxIncomingBuffer(buffer); 740 if (status != B_OK) { 741 TRACE_EPM(" ReceiveData(): no endpoint."); 742 // Send port unreachable error 743 domainSupport->Domain()->module->error_reply(NULL, buffer, 744 B_NET_ERROR_UNREACH_PORT, NULL); 745 return B_ERROR; 746 } 747 748 gBufferModule->free(buffer); 749 return B_OK; 750 } 751 752 753 status_t 754 UdpEndpointManager::ReceiveError(status_t error, net_buffer* buffer) 755 { 756 TRACE_EPM("ReceiveError(code %" B_PRId32 " %p [%" B_PRIu32 " bytes])", 757 error, buffer, buffer->size); 758 759 // We only really need the port information 760 if (buffer->size < 4) 761 return B_BAD_VALUE; 762 763 UdpDomainSupport* domainSupport = _GetDomainSupport(buffer); 764 if (domainSupport == NULL) { 765 // we don't instantiate domain supports in the receiving path, as 766 // we are only interested in delivering data to existing sockets. 767 return B_ERROR; 768 } 769 DomainSupportDeleter deleter(domainSupport); 770 771 // Deframe the buffer manually, as we usually only get 8 bytes from the 772 // original packet 773 udp_header header; 774 if (gBufferModule->read(buffer, 0, &header, 775 std::min((size_t)buffer->size, sizeof(udp_header))) != B_OK) { 776 return B_BAD_VALUE; 777 } 778 779 net_domain* domain = buffer->interface_address->domain; 780 net_address_module_info* addressModule = domain->address_module; 781 782 SocketAddress source(addressModule, buffer->source); 783 SocketAddress destination(addressModule, buffer->destination); 784 785 source.SetPort(header.source_port); 786 destination.SetPort(header.destination_port); 787 788 error = domainSupport->DeliverError(error, buffer); 789 return error; 790 } 791 792 793 status_t 794 UdpEndpointManager::Deframe(net_buffer* buffer) 795 { 796 TRACE_EPM("Deframe(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 797 798 NetBufferHeaderReader<udp_header> bufferHeader(buffer); 799 if (bufferHeader.Status() != B_OK) 800 return bufferHeader.Status(); 801 802 udp_header& header = bufferHeader.Data(); 803 804 net_domain* domain = _GetDomain(buffer); 805 if (domain == NULL) { 806 TRACE_EPM(" Deframe(): UDP packed dropped as there was no domain " 807 "specified (interface address %p).", buffer->interface_address); 808 return B_BAD_VALUE; 809 } 810 net_address_module_info* addressModule = domain->address_module; 811 812 SocketAddress source(addressModule, buffer->source); 813 SocketAddress destination(addressModule, buffer->destination); 814 815 source.SetPort(header.source_port); 816 destination.SetPort(header.destination_port); 817 818 TRACE_EPM(" Deframe(): data from %s to %s", source.AsString(true).Data(), 819 destination.AsString(true).Data()); 820 821 uint16 udpLength = ntohs(header.udp_length); 822 if (udpLength > buffer->size) { 823 TRACE_EPM(" Deframe(): buffer is too short, expected %hu.", 824 udpLength); 825 return B_MISMATCHED_VALUES; 826 } 827 828 if (buffer->size > udpLength) 829 gBufferModule->trim(buffer, udpLength); 830 831 if (header.udp_checksum != 0 && (buffer->buffer_flags & NET_BUFFER_L4_CHECKSUM_VALID) == 0) { 832 // check UDP-checksum (simulating a so-called "pseudo-header"): 833 uint16 sum = Checksum::PseudoHeader(addressModule, gBufferModule, 834 buffer, IPPROTO_UDP); 835 if (sum != 0) { 836 TRACE_EPM(" Deframe(): bad checksum 0x%hx.", sum); 837 return B_BAD_VALUE; 838 } 839 } 840 841 bufferHeader.Remove(); 842 // remove UDP-header from buffer before passing it on 843 844 return B_OK; 845 } 846 847 848 UdpDomainSupport * 849 UdpEndpointManager::OpenEndpoint(UdpEndpoint *endpoint) 850 { 851 MutexLocker _(fLock); 852 853 UdpDomainSupport* domain = _GetDomainSupport(endpoint->Domain(), true); 854 return domain; 855 } 856 857 858 status_t 859 UdpEndpointManager::FreeEndpoint(UdpDomainSupport *domain) 860 { 861 MutexLocker _(fLock); 862 863 if (domain->Put()) { 864 fDomains.Remove(domain); 865 delete domain; 866 } 867 868 return B_OK; 869 } 870 871 872 // #pragma mark - 873 874 875 inline net_domain* 876 UdpEndpointManager::_GetDomain(net_buffer* buffer) 877 { 878 if (buffer->interface_address != NULL) 879 return buffer->interface_address->domain; 880 881 return gStackModule->get_domain(buffer->destination->sa_family); 882 } 883 884 885 UdpDomainSupport* 886 UdpEndpointManager::_GetDomainSupport(net_domain* domain, bool create) 887 { 888 ASSERT_LOCKED_MUTEX(&fLock); 889 890 if (domain == NULL) 891 return NULL; 892 893 // TODO convert this into a Hashtable or install per-domain 894 // receiver handlers that forward the requests to the 895 // appropriate DemuxIncomingBuffer(). For instance, while 896 // being constructed UdpDomainSupport could call 897 // register_domain_receiving_protocol() with the right 898 // family. 899 UdpDomainList::Iterator iterator = fDomains.GetIterator(); 900 while (UdpDomainSupport* domainSupport = iterator.Next()) { 901 if (domainSupport->Domain() == domain) { 902 domainSupport->Ref(); 903 return domainSupport; 904 } 905 } 906 907 if (!create) 908 return NULL; 909 910 UdpDomainSupport* domainSupport 911 = new (std::nothrow) UdpDomainSupport(domain); 912 if (domainSupport == NULL || domainSupport->Init() < B_OK) { 913 delete domainSupport; 914 return NULL; 915 } 916 917 fDomains.Add(domainSupport); 918 domainSupport->Ref(); 919 return domainSupport; 920 } 921 922 923 /*! Retrieves the UdpDomainSupport object responsible for this buffer, if the 924 domain can be determined. This is only successful if the domain support is 925 already existing, ie. there must already be an endpoint for the domain. 926 */ 927 UdpDomainSupport* 928 UdpEndpointManager::_GetDomainSupport(net_buffer* buffer) 929 { 930 MutexLocker _(fLock); 931 932 return _GetDomainSupport(_GetDomain(buffer), false); 933 } 934 935 936 // #pragma mark - 937 938 939 UdpEndpoint::UdpEndpoint(net_socket *socket) 940 : 941 DatagramSocket<>("udp endpoint", socket), 942 fActive(false) 943 { 944 } 945 946 947 // #pragma mark - activation 948 949 950 status_t 951 UdpEndpoint::Bind(const sockaddr *address) 952 { 953 TRACE_EP("Bind(%s)", AddressString(Domain(), address, true).Data()); 954 return fManager->BindEndpoint(this, address); 955 } 956 957 958 status_t 959 UdpEndpoint::Unbind(sockaddr *address) 960 { 961 TRACE_EP("Unbind()"); 962 return fManager->UnbindEndpoint(this); 963 } 964 965 966 status_t 967 UdpEndpoint::Connect(const sockaddr *address) 968 { 969 TRACE_EP("Connect(%s)", AddressString(Domain(), address, true).Data()); 970 return fManager->ConnectEndpoint(this, address); 971 } 972 973 974 status_t 975 UdpEndpoint::Open() 976 { 977 TRACE_EP("Open()"); 978 979 AutoLocker _(fLock); 980 981 status_t status = ProtocolSocket::Open(); 982 if (status < B_OK) 983 return status; 984 985 fManager = sUdpEndpointManager->OpenEndpoint(this); 986 if (fManager == NULL) 987 return EAFNOSUPPORT; 988 989 return B_OK; 990 } 991 992 993 status_t 994 UdpEndpoint::Close() 995 { 996 TRACE_EP("Close()"); 997 fSocket->error = EBADF; 998 WakeAll(); 999 return B_OK; 1000 } 1001 1002 1003 status_t 1004 UdpEndpoint::Free() 1005 { 1006 TRACE_EP("Free()"); 1007 fManager->UnbindEndpoint(this); 1008 return sUdpEndpointManager->FreeEndpoint(fManager); 1009 } 1010 1011 1012 // #pragma mark - outbound 1013 1014 1015 status_t 1016 UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route) 1017 { 1018 TRACE_EP("SendRoutedData(%p [%" B_PRIu32 " bytes], %p)", buffer, 1019 buffer->size, route); 1020 1021 if (buffer->size > (0xffff - sizeof(udp_header))) 1022 return EMSGSIZE; 1023 1024 buffer->protocol = IPPROTO_UDP; 1025 1026 // add and fill UDP-specific header: 1027 NetBufferPrepend<udp_header> header(buffer); 1028 if (header.Status() < B_OK) 1029 return header.Status(); 1030 1031 header->source_port = AddressModule()->get_port(buffer->source); 1032 header->destination_port = AddressModule()->get_port(buffer->destination); 1033 header->udp_length = htons(buffer->size); 1034 // the udp-header is already included in the buffer-size 1035 header->udp_checksum = 0; 1036 1037 header.Sync(); 1038 1039 uint16 calculatedChecksum = Checksum::PseudoHeader(AddressModule(), 1040 gBufferModule, buffer, IPPROTO_UDP); 1041 if (calculatedChecksum == 0) 1042 calculatedChecksum = 0xffff; 1043 1044 *UDPChecksumField(buffer) = calculatedChecksum; 1045 buffer->buffer_flags |= NET_BUFFER_L4_CHECKSUM_VALID; 1046 1047 return next->module->send_routed_data(next, route, buffer); 1048 } 1049 1050 1051 status_t 1052 UdpEndpoint::SendData(net_buffer *buffer) 1053 { 1054 TRACE_EP("SendData(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1055 1056 return gDatalinkModule->send_data(this, NULL, buffer); 1057 } 1058 1059 1060 // #pragma mark - inbound 1061 1062 1063 ssize_t 1064 UdpEndpoint::BytesAvailable() 1065 { 1066 size_t bytes = AvailableData(); 1067 TRACE_EP("BytesAvailable(): %lu", bytes); 1068 return bytes; 1069 } 1070 1071 1072 status_t 1073 UdpEndpoint::FetchData(size_t numBytes, uint32 flags, net_buffer **_buffer) 1074 { 1075 TRACE_EP("FetchData(%" B_PRIuSIZE ", 0x%" B_PRIx32 ")", numBytes, flags); 1076 1077 status_t status = Dequeue(flags, _buffer); 1078 TRACE_EP(" FetchData(): returned from fifo status: %s", strerror(status)); 1079 if (status != B_OK) 1080 return status; 1081 1082 TRACE_EP(" FetchData(): returns buffer with %" B_PRIu32 " bytes", 1083 (*_buffer)->size); 1084 return B_OK; 1085 } 1086 1087 1088 status_t 1089 UdpEndpoint::StoreData(net_buffer *buffer) 1090 { 1091 TRACE_EP("StoreData(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1092 1093 return EnqueueClone(buffer); 1094 } 1095 1096 1097 status_t 1098 UdpEndpoint::DeliverData(net_buffer *_buffer) 1099 { 1100 TRACE_EP("DeliverData(%p [%" B_PRIu32 " bytes])", _buffer, _buffer->size); 1101 1102 net_buffer *buffer = gBufferModule->clone(_buffer, false); 1103 if (buffer == NULL) 1104 return B_NO_MEMORY; 1105 1106 status_t status = sUdpEndpointManager->Deframe(buffer); 1107 if (status < B_OK) { 1108 gBufferModule->free(buffer); 1109 return status; 1110 } 1111 1112 return Enqueue(buffer); 1113 } 1114 1115 1116 void 1117 UdpEndpoint::Dump() const 1118 { 1119 char local[64]; 1120 LocalAddress().AsString(local, sizeof(local), true); 1121 char peer[64]; 1122 PeerAddress().AsString(peer, sizeof(peer), true); 1123 1124 kprintf("%p %20s %20s %8lu\n", this, local, peer, fCurrentBytes); 1125 } 1126 1127 1128 // #pragma mark - protocol interface 1129 1130 1131 net_protocol * 1132 udp_init_protocol(net_socket *socket) 1133 { 1134 socket->protocol = IPPROTO_UDP; 1135 1136 UdpEndpoint *endpoint = new (std::nothrow) UdpEndpoint(socket); 1137 if (endpoint == NULL || endpoint->InitCheck() < B_OK) { 1138 delete endpoint; 1139 return NULL; 1140 } 1141 1142 return endpoint; 1143 } 1144 1145 1146 status_t 1147 udp_uninit_protocol(net_protocol *protocol) 1148 { 1149 delete (UdpEndpoint *)protocol; 1150 return B_OK; 1151 } 1152 1153 1154 status_t 1155 udp_open(net_protocol *protocol) 1156 { 1157 return ((UdpEndpoint *)protocol)->Open(); 1158 } 1159 1160 1161 status_t 1162 udp_close(net_protocol *protocol) 1163 { 1164 return ((UdpEndpoint *)protocol)->Close(); 1165 } 1166 1167 1168 status_t 1169 udp_free(net_protocol *protocol) 1170 { 1171 return ((UdpEndpoint *)protocol)->Free(); 1172 } 1173 1174 1175 status_t 1176 udp_connect(net_protocol *protocol, const struct sockaddr *address) 1177 { 1178 return ((UdpEndpoint *)protocol)->Connect(address); 1179 } 1180 1181 1182 status_t 1183 udp_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) 1184 { 1185 return B_NOT_SUPPORTED; 1186 } 1187 1188 1189 status_t 1190 udp_control(net_protocol *protocol, int level, int option, void *value, 1191 size_t *_length) 1192 { 1193 return protocol->next->module->control(protocol->next, level, option, 1194 value, _length); 1195 } 1196 1197 1198 status_t 1199 udp_getsockopt(net_protocol *protocol, int level, int option, void *value, 1200 int *length) 1201 { 1202 return protocol->next->module->getsockopt(protocol->next, level, option, 1203 value, length); 1204 } 1205 1206 1207 status_t 1208 udp_setsockopt(net_protocol *protocol, int level, int option, 1209 const void *value, int length) 1210 { 1211 return protocol->next->module->setsockopt(protocol->next, level, option, 1212 value, length); 1213 } 1214 1215 1216 status_t 1217 udp_bind(net_protocol *protocol, const struct sockaddr *address) 1218 { 1219 return ((UdpEndpoint *)protocol)->Bind(address); 1220 } 1221 1222 1223 status_t 1224 udp_unbind(net_protocol *protocol, struct sockaddr *address) 1225 { 1226 return ((UdpEndpoint *)protocol)->Unbind(address); 1227 } 1228 1229 1230 status_t 1231 udp_listen(net_protocol *protocol, int count) 1232 { 1233 return B_NOT_SUPPORTED; 1234 } 1235 1236 1237 status_t 1238 udp_shutdown(net_protocol *protocol, int direction) 1239 { 1240 return B_NOT_SUPPORTED; 1241 } 1242 1243 1244 status_t 1245 udp_send_routed_data(net_protocol *protocol, struct net_route *route, 1246 net_buffer *buffer) 1247 { 1248 return ((UdpEndpoint *)protocol)->SendRoutedData(buffer, route); 1249 } 1250 1251 1252 status_t 1253 udp_send_data(net_protocol *protocol, net_buffer *buffer) 1254 { 1255 return ((UdpEndpoint *)protocol)->SendData(buffer); 1256 } 1257 1258 1259 ssize_t 1260 udp_send_avail(net_protocol *protocol) 1261 { 1262 return protocol->socket->send.buffer_size; 1263 } 1264 1265 1266 status_t 1267 udp_read_data(net_protocol *protocol, size_t numBytes, uint32 flags, 1268 net_buffer **_buffer) 1269 { 1270 return ((UdpEndpoint *)protocol)->FetchData(numBytes, flags, _buffer); 1271 } 1272 1273 1274 ssize_t 1275 udp_read_avail(net_protocol *protocol) 1276 { 1277 return ((UdpEndpoint *)protocol)->BytesAvailable(); 1278 } 1279 1280 1281 struct net_domain * 1282 udp_get_domain(net_protocol *protocol) 1283 { 1284 return protocol->next->module->get_domain(protocol->next); 1285 } 1286 1287 1288 size_t 1289 udp_get_mtu(net_protocol *protocol, const struct sockaddr *address) 1290 { 1291 return protocol->next->module->get_mtu(protocol->next, address); 1292 } 1293 1294 1295 status_t 1296 udp_receive_data(net_buffer *buffer) 1297 { 1298 return sUdpEndpointManager->ReceiveData(buffer); 1299 } 1300 1301 1302 status_t 1303 udp_deliver_data(net_protocol *protocol, net_buffer *buffer) 1304 { 1305 return ((UdpEndpoint *)protocol)->DeliverData(buffer); 1306 } 1307 1308 1309 status_t 1310 udp_error_received(net_error error, net_buffer* buffer) 1311 { 1312 status_t notifyError = B_OK; 1313 1314 switch (error) { 1315 case B_NET_ERROR_UNREACH_NET: 1316 notifyError = ENETUNREACH; 1317 break; 1318 case B_NET_ERROR_UNREACH_HOST: 1319 case B_NET_ERROR_TRANSIT_TIME_EXCEEDED: 1320 notifyError = EHOSTUNREACH; 1321 break; 1322 case B_NET_ERROR_UNREACH_PROTOCOL: 1323 case B_NET_ERROR_UNREACH_PORT: 1324 notifyError = ECONNREFUSED; 1325 break; 1326 case B_NET_ERROR_MESSAGE_SIZE: 1327 notifyError = EMSGSIZE; 1328 break; 1329 case B_NET_ERROR_PARAMETER_PROBLEM: 1330 notifyError = ENOPROTOOPT; 1331 break; 1332 1333 case B_NET_ERROR_QUENCH: 1334 default: 1335 // ignore them 1336 gBufferModule->free(buffer); 1337 return B_OK; 1338 } 1339 1340 ASSERT(notifyError != B_OK); 1341 1342 return sUdpEndpointManager->ReceiveError(notifyError, buffer); 1343 } 1344 1345 1346 status_t 1347 udp_error_reply(net_protocol *protocol, net_buffer *cause, net_error error, 1348 net_error_data *errorData) 1349 { 1350 return B_ERROR; 1351 } 1352 1353 1354 ssize_t 1355 udp_process_ancillary_data_no_container(net_protocol *protocol, 1356 net_buffer* buffer, void *data, size_t dataSize) 1357 { 1358 return protocol->next->module->process_ancillary_data_no_container( 1359 protocol, buffer, data, dataSize); 1360 } 1361 1362 1363 // #pragma mark - module interface 1364 1365 1366 static status_t 1367 init_udp() 1368 { 1369 status_t status; 1370 TRACE_EPM("init_udp()"); 1371 1372 sUdpEndpointManager = new (std::nothrow) UdpEndpointManager; 1373 if (sUdpEndpointManager == NULL) 1374 return B_NO_MEMORY; 1375 1376 status = sUdpEndpointManager->InitCheck(); 1377 if (status != B_OK) 1378 goto err1; 1379 1380 status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, 1381 IPPROTO_IP, 1382 "network/protocols/udp/v1", 1383 "network/protocols/ipv4/v1", 1384 NULL); 1385 if (status < B_OK) 1386 goto err1; 1387 status = gStackModule->register_domain_protocols(AF_INET6, SOCK_DGRAM, 1388 IPPROTO_IP, 1389 "network/protocols/udp/v1", 1390 "network/protocols/ipv6/v1", 1391 NULL); 1392 if (status < B_OK) 1393 goto err1; 1394 1395 status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, 1396 IPPROTO_UDP, 1397 "network/protocols/udp/v1", 1398 "network/protocols/ipv4/v1", 1399 NULL); 1400 if (status < B_OK) 1401 goto err1; 1402 status = gStackModule->register_domain_protocols(AF_INET6, SOCK_DGRAM, 1403 IPPROTO_UDP, 1404 "network/protocols/udp/v1", 1405 "network/protocols/ipv6/v1", 1406 NULL); 1407 if (status < B_OK) 1408 goto err1; 1409 1410 status = gStackModule->register_domain_receiving_protocol(AF_INET, 1411 IPPROTO_UDP, "network/protocols/udp/v1"); 1412 if (status < B_OK) 1413 goto err1; 1414 status = gStackModule->register_domain_receiving_protocol(AF_INET6, 1415 IPPROTO_UDP, "network/protocols/udp/v1"); 1416 if (status < B_OK) 1417 goto err1; 1418 1419 add_debugger_command("udp_endpoints", UdpEndpointManager::DumpEndpoints, 1420 "lists all open UDP endpoints"); 1421 1422 return B_OK; 1423 1424 err1: 1425 // TODO: shouldn't unregister the protocols here? 1426 delete sUdpEndpointManager; 1427 1428 TRACE_EPM("init_udp() fails with %" B_PRIx32 " (%s)", status, 1429 strerror(status)); 1430 return status; 1431 } 1432 1433 1434 static status_t 1435 uninit_udp() 1436 { 1437 TRACE_EPM("uninit_udp()"); 1438 remove_debugger_command("udp_endpoints", 1439 UdpEndpointManager::DumpEndpoints); 1440 delete sUdpEndpointManager; 1441 return B_OK; 1442 } 1443 1444 1445 static status_t 1446 udp_std_ops(int32 op, ...) 1447 { 1448 switch (op) { 1449 case B_MODULE_INIT: 1450 return init_udp(); 1451 1452 case B_MODULE_UNINIT: 1453 return uninit_udp(); 1454 1455 default: 1456 return B_ERROR; 1457 } 1458 } 1459 1460 1461 net_protocol_module_info sUDPModule = { 1462 { 1463 "network/protocols/udp/v1", 1464 0, 1465 udp_std_ops 1466 }, 1467 NET_PROTOCOL_ATOMIC_MESSAGES, 1468 1469 udp_init_protocol, 1470 udp_uninit_protocol, 1471 udp_open, 1472 udp_close, 1473 udp_free, 1474 udp_connect, 1475 udp_accept, 1476 udp_control, 1477 udp_getsockopt, 1478 udp_setsockopt, 1479 udp_bind, 1480 udp_unbind, 1481 udp_listen, 1482 udp_shutdown, 1483 udp_send_data, 1484 udp_send_routed_data, 1485 udp_send_avail, 1486 udp_read_data, 1487 udp_read_avail, 1488 udp_get_domain, 1489 udp_get_mtu, 1490 udp_receive_data, 1491 udp_deliver_data, 1492 udp_error_received, 1493 udp_error_reply, 1494 NULL, // add_ancillary_data() 1495 NULL, // process_ancillary_data() 1496 udp_process_ancillary_data_no_container, 1497 NULL, // send_data_no_buffer() 1498 NULL // read_data_no_buffer() 1499 }; 1500 1501 module_dependency module_dependencies[] = { 1502 {NET_STACK_MODULE_NAME, (module_info **)&gStackModule}, 1503 {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule}, 1504 {NET_DATALINK_MODULE_NAME, (module_info **)&gDatalinkModule}, 1505 {NET_SOCKET_MODULE_NAME, (module_info **)&gSocketModule}, 1506 {} 1507 }; 1508 1509 module_info *modules[] = { 1510 (module_info *)&sUDPModule, 1511 NULL 1512 }; 1513