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