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