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->flags & MSG_BCAST) != 0) 295 return _DemuxBroadcast(buffer); 296 if ((buffer->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->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) { 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 UdpDomainSupport* support = _GetDomainSupport(_GetDomain(buffer), false); 933 if (support != NULL) 934 support->Ref(); 935 return support; 936 } 937 938 939 // #pragma mark - 940 941 942 UdpEndpoint::UdpEndpoint(net_socket *socket) 943 : 944 DatagramSocket<>("udp endpoint", socket), 945 fActive(false) 946 { 947 } 948 949 950 // #pragma mark - activation 951 952 953 status_t 954 UdpEndpoint::Bind(const sockaddr *address) 955 { 956 TRACE_EP("Bind(%s)", AddressString(Domain(), address, true).Data()); 957 return fManager->BindEndpoint(this, address); 958 } 959 960 961 status_t 962 UdpEndpoint::Unbind(sockaddr *address) 963 { 964 TRACE_EP("Unbind()"); 965 return fManager->UnbindEndpoint(this); 966 } 967 968 969 status_t 970 UdpEndpoint::Connect(const sockaddr *address) 971 { 972 TRACE_EP("Connect(%s)", AddressString(Domain(), address, true).Data()); 973 return fManager->ConnectEndpoint(this, address); 974 } 975 976 977 status_t 978 UdpEndpoint::Open() 979 { 980 TRACE_EP("Open()"); 981 982 AutoLocker _(fLock); 983 984 status_t status = ProtocolSocket::Open(); 985 if (status < B_OK) 986 return status; 987 988 fManager = sUdpEndpointManager->OpenEndpoint(this); 989 if (fManager == NULL) 990 return EAFNOSUPPORT; 991 992 return B_OK; 993 } 994 995 996 status_t 997 UdpEndpoint::Close() 998 { 999 TRACE_EP("Close()"); 1000 fSocket->error = EBADF; 1001 WakeAll(); 1002 return B_OK; 1003 } 1004 1005 1006 status_t 1007 UdpEndpoint::Free() 1008 { 1009 TRACE_EP("Free()"); 1010 fManager->UnbindEndpoint(this); 1011 return sUdpEndpointManager->FreeEndpoint(fManager); 1012 } 1013 1014 1015 // #pragma mark - outbound 1016 1017 1018 status_t 1019 UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route) 1020 { 1021 TRACE_EP("SendRoutedData(%p [%" B_PRIu32 " bytes], %p)", buffer, 1022 buffer->size, route); 1023 1024 if (buffer->size > (0xffff - sizeof(udp_header))) 1025 return EMSGSIZE; 1026 1027 buffer->protocol = IPPROTO_UDP; 1028 1029 // add and fill UDP-specific header: 1030 NetBufferPrepend<udp_header> header(buffer); 1031 if (header.Status() < B_OK) 1032 return header.Status(); 1033 1034 header->source_port = AddressModule()->get_port(buffer->source); 1035 header->destination_port = AddressModule()->get_port(buffer->destination); 1036 header->udp_length = htons(buffer->size); 1037 // the udp-header is already included in the buffer-size 1038 header->udp_checksum = 0; 1039 1040 header.Sync(); 1041 1042 uint16 calculatedChecksum = Checksum::PseudoHeader(AddressModule(), 1043 gBufferModule, buffer, IPPROTO_UDP); 1044 if (calculatedChecksum == 0) 1045 calculatedChecksum = 0xffff; 1046 1047 *UDPChecksumField(buffer) = calculatedChecksum; 1048 1049 return next->module->send_routed_data(next, route, buffer); 1050 } 1051 1052 1053 status_t 1054 UdpEndpoint::SendData(net_buffer *buffer) 1055 { 1056 TRACE_EP("SendData(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1057 1058 return gDatalinkModule->send_data(this, NULL, buffer); 1059 } 1060 1061 1062 // #pragma mark - inbound 1063 1064 1065 ssize_t 1066 UdpEndpoint::BytesAvailable() 1067 { 1068 size_t bytes = AvailableData(); 1069 TRACE_EP("BytesAvailable(): %lu", bytes); 1070 return bytes; 1071 } 1072 1073 1074 status_t 1075 UdpEndpoint::FetchData(size_t numBytes, uint32 flags, net_buffer **_buffer) 1076 { 1077 TRACE_EP("FetchData(%" B_PRIuSIZE ", 0x%" B_PRIx32 ")", numBytes, flags); 1078 1079 status_t status = Dequeue(flags, _buffer); 1080 TRACE_EP(" FetchData(): returned from fifo status: %s", strerror(status)); 1081 if (status != B_OK) 1082 return status; 1083 1084 TRACE_EP(" FetchData(): returns buffer with %" B_PRIu32 " bytes", 1085 (*_buffer)->size); 1086 return B_OK; 1087 } 1088 1089 1090 status_t 1091 UdpEndpoint::StoreData(net_buffer *buffer) 1092 { 1093 TRACE_EP("StoreData(%p [%" B_PRIu32 " bytes])", buffer, buffer->size); 1094 1095 return EnqueueClone(buffer); 1096 } 1097 1098 1099 status_t 1100 UdpEndpoint::DeliverData(net_buffer *_buffer) 1101 { 1102 TRACE_EP("DeliverData(%p [%" B_PRIu32 " bytes])", _buffer, _buffer->size); 1103 1104 net_buffer *buffer = gBufferModule->clone(_buffer, false); 1105 if (buffer == NULL) 1106 return B_NO_MEMORY; 1107 1108 status_t status = sUdpEndpointManager->Deframe(buffer); 1109 if (status < B_OK) { 1110 gBufferModule->free(buffer); 1111 return status; 1112 } 1113 1114 return Enqueue(buffer); 1115 } 1116 1117 1118 void 1119 UdpEndpoint::Dump() const 1120 { 1121 char local[64]; 1122 LocalAddress().AsString(local, sizeof(local), true); 1123 char peer[64]; 1124 PeerAddress().AsString(peer, sizeof(peer), true); 1125 1126 kprintf("%p %20s %20s %8lu\n", this, local, peer, fCurrentBytes); 1127 } 1128 1129 1130 // #pragma mark - protocol interface 1131 1132 1133 net_protocol * 1134 udp_init_protocol(net_socket *socket) 1135 { 1136 socket->protocol = IPPROTO_UDP; 1137 1138 UdpEndpoint *endpoint = new (std::nothrow) UdpEndpoint(socket); 1139 if (endpoint == NULL || endpoint->InitCheck() < B_OK) { 1140 delete endpoint; 1141 return NULL; 1142 } 1143 1144 return endpoint; 1145 } 1146 1147 1148 status_t 1149 udp_uninit_protocol(net_protocol *protocol) 1150 { 1151 delete (UdpEndpoint *)protocol; 1152 return B_OK; 1153 } 1154 1155 1156 status_t 1157 udp_open(net_protocol *protocol) 1158 { 1159 return ((UdpEndpoint *)protocol)->Open(); 1160 } 1161 1162 1163 status_t 1164 udp_close(net_protocol *protocol) 1165 { 1166 return ((UdpEndpoint *)protocol)->Close(); 1167 } 1168 1169 1170 status_t 1171 udp_free(net_protocol *protocol) 1172 { 1173 return ((UdpEndpoint *)protocol)->Free(); 1174 } 1175 1176 1177 status_t 1178 udp_connect(net_protocol *protocol, const struct sockaddr *address) 1179 { 1180 return ((UdpEndpoint *)protocol)->Connect(address); 1181 } 1182 1183 1184 status_t 1185 udp_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) 1186 { 1187 return B_NOT_SUPPORTED; 1188 } 1189 1190 1191 status_t 1192 udp_control(net_protocol *protocol, int level, int option, void *value, 1193 size_t *_length) 1194 { 1195 return protocol->next->module->control(protocol->next, level, option, 1196 value, _length); 1197 } 1198 1199 1200 status_t 1201 udp_getsockopt(net_protocol *protocol, int level, int option, void *value, 1202 int *length) 1203 { 1204 return protocol->next->module->getsockopt(protocol->next, level, option, 1205 value, length); 1206 } 1207 1208 1209 status_t 1210 udp_setsockopt(net_protocol *protocol, int level, int option, 1211 const void *value, int length) 1212 { 1213 return protocol->next->module->setsockopt(protocol->next, level, option, 1214 value, length); 1215 } 1216 1217 1218 status_t 1219 udp_bind(net_protocol *protocol, const struct sockaddr *address) 1220 { 1221 return ((UdpEndpoint *)protocol)->Bind(address); 1222 } 1223 1224 1225 status_t 1226 udp_unbind(net_protocol *protocol, struct sockaddr *address) 1227 { 1228 return ((UdpEndpoint *)protocol)->Unbind(address); 1229 } 1230 1231 1232 status_t 1233 udp_listen(net_protocol *protocol, int count) 1234 { 1235 return B_NOT_SUPPORTED; 1236 } 1237 1238 1239 status_t 1240 udp_shutdown(net_protocol *protocol, int direction) 1241 { 1242 return B_NOT_SUPPORTED; 1243 } 1244 1245 1246 status_t 1247 udp_send_routed_data(net_protocol *protocol, struct net_route *route, 1248 net_buffer *buffer) 1249 { 1250 return ((UdpEndpoint *)protocol)->SendRoutedData(buffer, route); 1251 } 1252 1253 1254 status_t 1255 udp_send_data(net_protocol *protocol, net_buffer *buffer) 1256 { 1257 return ((UdpEndpoint *)protocol)->SendData(buffer); 1258 } 1259 1260 1261 ssize_t 1262 udp_send_avail(net_protocol *protocol) 1263 { 1264 return protocol->socket->send.buffer_size; 1265 } 1266 1267 1268 status_t 1269 udp_read_data(net_protocol *protocol, size_t numBytes, uint32 flags, 1270 net_buffer **_buffer) 1271 { 1272 return ((UdpEndpoint *)protocol)->FetchData(numBytes, flags, _buffer); 1273 } 1274 1275 1276 ssize_t 1277 udp_read_avail(net_protocol *protocol) 1278 { 1279 return ((UdpEndpoint *)protocol)->BytesAvailable(); 1280 } 1281 1282 1283 struct net_domain * 1284 udp_get_domain(net_protocol *protocol) 1285 { 1286 return protocol->next->module->get_domain(protocol->next); 1287 } 1288 1289 1290 size_t 1291 udp_get_mtu(net_protocol *protocol, const struct sockaddr *address) 1292 { 1293 return protocol->next->module->get_mtu(protocol->next, address); 1294 } 1295 1296 1297 status_t 1298 udp_receive_data(net_buffer *buffer) 1299 { 1300 return sUdpEndpointManager->ReceiveData(buffer); 1301 } 1302 1303 1304 status_t 1305 udp_deliver_data(net_protocol *protocol, net_buffer *buffer) 1306 { 1307 return ((UdpEndpoint *)protocol)->DeliverData(buffer); 1308 } 1309 1310 1311 status_t 1312 udp_error_received(net_error error, net_buffer* buffer) 1313 { 1314 status_t notifyError = B_OK; 1315 1316 switch (error) { 1317 case B_NET_ERROR_UNREACH_NET: 1318 notifyError = ENETUNREACH; 1319 break; 1320 case B_NET_ERROR_UNREACH_HOST: 1321 case B_NET_ERROR_TRANSIT_TIME_EXCEEDED: 1322 notifyError = EHOSTUNREACH; 1323 break; 1324 case B_NET_ERROR_UNREACH_PROTOCOL: 1325 case B_NET_ERROR_UNREACH_PORT: 1326 notifyError = ECONNREFUSED; 1327 break; 1328 case B_NET_ERROR_MESSAGE_SIZE: 1329 notifyError = EMSGSIZE; 1330 break; 1331 case B_NET_ERROR_PARAMETER_PROBLEM: 1332 notifyError = ENOPROTOOPT; 1333 break; 1334 1335 case B_NET_ERROR_QUENCH: 1336 default: 1337 // ignore them 1338 gBufferModule->free(buffer); 1339 return B_OK; 1340 } 1341 1342 ASSERT(notifyError != B_OK); 1343 1344 return sUdpEndpointManager->ReceiveError(notifyError, buffer); 1345 } 1346 1347 1348 status_t 1349 udp_error_reply(net_protocol *protocol, net_buffer *cause, net_error error, 1350 net_error_data *errorData) 1351 { 1352 return B_ERROR; 1353 } 1354 1355 1356 ssize_t 1357 udp_process_ancillary_data_no_container(net_protocol *protocol, 1358 net_buffer* buffer, void *data, size_t dataSize) 1359 { 1360 return protocol->next->module->process_ancillary_data_no_container( 1361 protocol, buffer, data, dataSize); 1362 } 1363 1364 1365 // #pragma mark - module interface 1366 1367 1368 static status_t 1369 init_udp() 1370 { 1371 status_t status; 1372 TRACE_EPM("init_udp()"); 1373 1374 sUdpEndpointManager = new (std::nothrow) UdpEndpointManager; 1375 if (sUdpEndpointManager == NULL) 1376 return B_NO_MEMORY; 1377 1378 status = sUdpEndpointManager->InitCheck(); 1379 if (status != B_OK) 1380 goto err1; 1381 1382 status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, 1383 IPPROTO_IP, 1384 "network/protocols/udp/v1", 1385 "network/protocols/ipv4/v1", 1386 NULL); 1387 if (status < B_OK) 1388 goto err1; 1389 status = gStackModule->register_domain_protocols(AF_INET6, SOCK_DGRAM, 1390 IPPROTO_IP, 1391 "network/protocols/udp/v1", 1392 "network/protocols/ipv6/v1", 1393 NULL); 1394 if (status < B_OK) 1395 goto err1; 1396 1397 status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, 1398 IPPROTO_UDP, 1399 "network/protocols/udp/v1", 1400 "network/protocols/ipv4/v1", 1401 NULL); 1402 if (status < B_OK) 1403 goto err1; 1404 status = gStackModule->register_domain_protocols(AF_INET6, SOCK_DGRAM, 1405 IPPROTO_UDP, 1406 "network/protocols/udp/v1", 1407 "network/protocols/ipv6/v1", 1408 NULL); 1409 if (status < B_OK) 1410 goto err1; 1411 1412 status = gStackModule->register_domain_receiving_protocol(AF_INET, 1413 IPPROTO_UDP, "network/protocols/udp/v1"); 1414 if (status < B_OK) 1415 goto err1; 1416 status = gStackModule->register_domain_receiving_protocol(AF_INET6, 1417 IPPROTO_UDP, "network/protocols/udp/v1"); 1418 if (status < B_OK) 1419 goto err1; 1420 1421 add_debugger_command("udp_endpoints", UdpEndpointManager::DumpEndpoints, 1422 "lists all open UDP endpoints"); 1423 1424 return B_OK; 1425 1426 err1: 1427 // TODO: shouldn't unregister the protocols here? 1428 delete sUdpEndpointManager; 1429 1430 TRACE_EPM("init_udp() fails with %" B_PRIx32 " (%s)", status, 1431 strerror(status)); 1432 return status; 1433 } 1434 1435 1436 static status_t 1437 uninit_udp() 1438 { 1439 TRACE_EPM("uninit_udp()"); 1440 remove_debugger_command("udp_endpoints", 1441 UdpEndpointManager::DumpEndpoints); 1442 delete sUdpEndpointManager; 1443 return B_OK; 1444 } 1445 1446 1447 static status_t 1448 udp_std_ops(int32 op, ...) 1449 { 1450 switch (op) { 1451 case B_MODULE_INIT: 1452 return init_udp(); 1453 1454 case B_MODULE_UNINIT: 1455 return uninit_udp(); 1456 1457 default: 1458 return B_ERROR; 1459 } 1460 } 1461 1462 1463 net_protocol_module_info sUDPModule = { 1464 { 1465 "network/protocols/udp/v1", 1466 0, 1467 udp_std_ops 1468 }, 1469 NET_PROTOCOL_ATOMIC_MESSAGES, 1470 1471 udp_init_protocol, 1472 udp_uninit_protocol, 1473 udp_open, 1474 udp_close, 1475 udp_free, 1476 udp_connect, 1477 udp_accept, 1478 udp_control, 1479 udp_getsockopt, 1480 udp_setsockopt, 1481 udp_bind, 1482 udp_unbind, 1483 udp_listen, 1484 udp_shutdown, 1485 udp_send_data, 1486 udp_send_routed_data, 1487 udp_send_avail, 1488 udp_read_data, 1489 udp_read_avail, 1490 udp_get_domain, 1491 udp_get_mtu, 1492 udp_receive_data, 1493 udp_deliver_data, 1494 udp_error_received, 1495 udp_error_reply, 1496 NULL, // add_ancillary_data() 1497 NULL, // process_ancillary_data() 1498 udp_process_ancillary_data_no_container, 1499 NULL, // send_data_no_buffer() 1500 NULL // read_data_no_buffer() 1501 }; 1502 1503 module_dependency module_dependencies[] = { 1504 {NET_STACK_MODULE_NAME, (module_info **)&gStackModule}, 1505 {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule}, 1506 {NET_DATALINK_MODULE_NAME, (module_info **)&gDatalinkModule}, 1507 {NET_SOCKET_MODULE_NAME, (module_info **)&gSocketModule}, 1508 {} 1509 }; 1510 1511 module_info *modules[] = { 1512 (module_info *)&sUDPModule, 1513 NULL 1514 }; 1515