1 /* 2 * Copyright 2006, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Oliver Tappe, zooey@hirschkaefer.de 7 */ 8 9 10 #include <net_buffer.h> 11 #include <net_datalink.h> 12 #include <net_protocol.h> 13 #include <net_stack.h> 14 15 #include <lock.h> 16 #include <util/AutoLock.h> 17 #include <util/khash.h> 18 19 #include <KernelExport.h> 20 21 #include <NetBufferUtilities.h> 22 #include <NetUtilities.h> 23 24 #include <netinet/in.h> 25 #include <new> 26 #include <stdlib.h> 27 #include <string.h> 28 29 30 #define TRACE_UDP 31 #ifdef TRACE_UDP 32 # define TRACE(x) dprintf x 33 # define TRACE_BLOCK(x) dump_block x 34 #else 35 # define TRACE(x) 36 # define TRACE_BLOCK(x) 37 #endif 38 39 40 struct udp_header { 41 uint16 source_port; 42 uint16 destination_port; 43 uint16 udp_length; 44 uint16 udp_checksum; 45 } _PACKED; 46 47 48 class UdpEndpoint : public net_protocol { 49 public: 50 UdpEndpoint(net_socket *socket); 51 ~UdpEndpoint(); 52 53 status_t Bind(sockaddr *newAddr); 54 status_t Unbind(sockaddr *newAddr); 55 status_t Connect(const sockaddr *newAddr); 56 57 status_t Open(); 58 status_t Close(); 59 status_t Free(); 60 61 status_t SendData(net_buffer *buffer, net_route *route); 62 63 ssize_t BytesAvailable(); 64 status_t FetchData(size_t numBytes, uint32 flags, 65 net_buffer **_buffer); 66 67 status_t StoreData(net_buffer *buffer); 68 69 UdpEndpoint *hash_link; 70 // link required by hash_table (see khash.h) 71 private: 72 status_t _Activate(); 73 status_t _Deactivate(); 74 75 bool fActive; 76 // an active UdpEndpoint is part of the endpoint 77 // hash (and it is bound and optionally connected) 78 net_fifo fFifo; 79 // storage space for incoming data 80 }; 81 82 83 class UdpEndpointManager { 84 85 struct hash_key { 86 hash_key(sockaddr *ourAddress, sockaddr *peerAddress); 87 88 sockaddr ourAddress; 89 sockaddr peerAddress; 90 }; 91 92 class Ephemerals { 93 public: 94 Ephemerals(); 95 ~Ephemerals(); 96 97 uint16 GetNext(hash_table *activeEndpoints); 98 static const uint16 kFirst = 49152; 99 static const uint16 kLast = 65535; 100 private: 101 uint16 fLastUsed; 102 }; 103 104 public: 105 UdpEndpointManager(); 106 ~UdpEndpointManager(); 107 108 status_t DemuxBroadcast(net_buffer *buffer); 109 status_t DemuxMulticast(net_buffer *buffer); 110 status_t DemuxUnicast(net_buffer *buffer); 111 status_t DemuxIncomingBuffer(net_buffer *buffer); 112 status_t ReceiveData(net_buffer *buffer); 113 114 static int Compare(void *udpEndpoint, const void *_key); 115 static uint32 ComputeHash(sockaddr *ourAddress, sockaddr *peerAddress); 116 static uint32 Hash(void *udpEndpoint, const void *key, uint32 range); 117 118 UdpEndpoint *FindActiveEndpoint(sockaddr *ourAddress, 119 sockaddr *peerAddress); 120 status_t CheckBindRequest(sockaddr *address, int socketOptions); 121 122 status_t ActivateEndpoint(UdpEndpoint *endpoint); 123 status_t DeactivateEndpoint(UdpEndpoint *endpoint); 124 125 status_t OpenEndpoint(UdpEndpoint *endpoint); 126 status_t CloseEndpoint(UdpEndpoint *endpoint); 127 status_t FreeEndpoint(UdpEndpoint *endpoint); 128 129 uint16 GetEphemeralPort(); 130 131 benaphore *Locker(); 132 status_t InitCheck() const; 133 private: 134 benaphore fLock; 135 hash_table *fActiveEndpoints; 136 static const uint32 kNumHashBuckets = 0x800; 137 // if you change this, adjust the shifting in 138 // Hash() accordingly! 139 Ephemerals fEphemerals; 140 status_t fStatus; 141 uint32 fEndpointCount; 142 }; 143 144 145 static UdpEndpointManager *sUdpEndpointManager; 146 147 static net_domain *sDomain; 148 149 static net_address_module_info *sAddressModule; 150 net_buffer_module_info *sBufferModule; 151 static net_datalink_module_info *sDatalinkModule; 152 static net_stack_module_info *sStackModule; 153 154 155 // #pragma mark - 156 157 158 UdpEndpointManager::hash_key::hash_key(sockaddr *_ourAddress, sockaddr *_peerAddress) 159 { 160 memcpy(&ourAddress, _ourAddress, sizeof(sockaddr)); 161 memcpy(&peerAddress, _peerAddress, sizeof(sockaddr)); 162 } 163 164 165 // #pragma mark - 166 167 168 UdpEndpointManager::Ephemerals::Ephemerals() 169 : 170 fLastUsed(kLast) 171 { 172 } 173 174 175 UdpEndpointManager::Ephemerals::~Ephemerals() 176 { 177 } 178 179 180 uint16 181 UdpEndpointManager::Ephemerals::GetNext(hash_table *activeEndpoints) 182 { 183 uint16 stop, curr, ncurr; 184 if (fLastUsed < kLast) { 185 stop = fLastUsed; 186 curr = fLastUsed + 1; 187 } else { 188 stop = kLast; 189 curr = kFirst; 190 } 191 192 TRACE(("UdpEndpointManager::Ephemerals::GetNext()...\n")); 193 // TODO: a free list could be used to avoid the impact of these 194 // two nested loops most of the time... let's see how bad this really is 195 UdpEndpoint *endpoint; 196 struct hash_iterator endpointIterator; 197 hash_open(activeEndpoints, &endpointIterator); 198 bool found = false; 199 uint16 endpointPort; 200 while(!found && curr != stop) { 201 TRACE(("...trying port %u...\n", curr)); 202 ncurr = htons(curr); 203 for(hash_rewind(activeEndpoints, &endpointIterator); !found; ) { 204 endpoint = (UdpEndpoint *)hash_next(activeEndpoints, &endpointIterator); 205 if (!endpoint) { 206 found = true; 207 break; 208 } 209 endpointPort = sAddressModule->get_port( 210 (sockaddr *)&endpoint->socket->address); 211 TRACE(("...checking endpoint %p (port=%u)...\n", endpoint, 212 ntohs(endpointPort))); 213 if (endpointPort == ncurr) 214 break; 215 } 216 if (!found) { 217 if (curr < kLast) 218 curr++; 219 else 220 curr = kFirst; 221 } 222 } 223 hash_close(activeEndpoints, &endpointIterator, false); 224 if (!found) 225 return 0; 226 TRACE(("...using port %u\n", curr)); 227 fLastUsed = curr; 228 return curr; 229 } 230 231 232 // #pragma mark - 233 234 235 UdpEndpointManager::UdpEndpointManager() 236 : 237 fStatus(B_NO_INIT), 238 fEndpointCount(0) 239 { 240 fActiveEndpoints = hash_init(kNumHashBuckets, offsetof(UdpEndpoint, hash_link), 241 &Compare, &Hash); 242 if (fActiveEndpoints == NULL) { 243 fStatus = B_NO_MEMORY; 244 return; 245 } 246 247 fStatus = benaphore_init(&fLock, "UDP endpoints"); 248 if (fStatus < B_OK) 249 hash_uninit(fActiveEndpoints); 250 } 251 252 253 UdpEndpointManager::~UdpEndpointManager() 254 { 255 benaphore_destroy(&fLock); 256 hash_uninit(fActiveEndpoints); 257 } 258 259 260 inline benaphore * 261 UdpEndpointManager::Locker() 262 { 263 return &fLock; 264 } 265 266 267 inline status_t 268 UdpEndpointManager::InitCheck() const 269 { 270 return fStatus; 271 } 272 273 274 // #pragma mark - hashing 275 276 277 /*static*/ int 278 UdpEndpointManager::Compare(void *_udpEndpoint, const void *_key) 279 { 280 struct UdpEndpoint *udpEndpoint = (UdpEndpoint*)_udpEndpoint; 281 hash_key *key = (hash_key *)_key; 282 283 sockaddr *ourAddr = (sockaddr *)&udpEndpoint->socket->address; 284 sockaddr *peerAddr = (sockaddr *)&udpEndpoint->socket->peer; 285 286 if (sAddressModule->equal_addresses_and_ports(ourAddr, &key->ourAddress) 287 && sAddressModule->equal_addresses_and_ports(peerAddr, &key->peerAddress)) 288 return 0; 289 290 return 1; 291 } 292 293 294 /*static*/ inline uint32 295 UdpEndpointManager::ComputeHash(sockaddr *ourAddress, sockaddr *peerAddress) 296 { 297 return sAddressModule->hash_address_pair(ourAddress, peerAddress); 298 } 299 300 301 /*static*/ uint32 302 UdpEndpointManager::Hash(void *_udpEndpoint, const void *_key, uint32 range) 303 { 304 uint32 hash; 305 306 if (_udpEndpoint) { 307 struct UdpEndpoint *udpEndpoint = (UdpEndpoint*)_udpEndpoint; 308 sockaddr *ourAddr = (sockaddr*)&udpEndpoint->socket->address; 309 sockaddr *peerAddr = (sockaddr*)&udpEndpoint->socket->peer; 310 hash = ComputeHash(ourAddr, peerAddr); 311 } else { 312 hash_key *key = (hash_key *)_key; 313 hash = ComputeHash(&key->ourAddress, &key->peerAddress); 314 } 315 316 // move the bits into the relevant range (as defined by kNumHashBuckets): 317 hash = (hash & 0x000007FF) ^ (hash & 0x003FF800) >> 11 318 ^ (hash & 0xFFC00000UL) >> 22; 319 320 TRACE(("UDP-endpoint hash is %lx\n", hash % range)); 321 return hash % range; 322 } 323 324 325 // #pragma mark - inbound 326 327 328 UdpEndpoint * 329 UdpEndpointManager::FindActiveEndpoint(sockaddr *ourAddress, 330 sockaddr *peerAddress) 331 { 332 TRACE(("trying to find UDP-endpoint for (l:%s p:%s)\n", 333 AddressString(sDomain, ourAddress, true).Data(), 334 AddressString(sDomain, peerAddress, true).Data())); 335 hash_key key(ourAddress, peerAddress); 336 UdpEndpoint *endpoint = (UdpEndpoint *)hash_lookup(fActiveEndpoints, &key); 337 return endpoint; 338 } 339 340 341 status_t 342 UdpEndpointManager::DemuxBroadcast(net_buffer *buffer) 343 { 344 sockaddr *peerAddr = (sockaddr *)&buffer->source; 345 sockaddr *broadcastAddr = (sockaddr *)&buffer->destination; 346 sockaddr *mask = NULL; 347 if (buffer->interface) 348 mask = (sockaddr *)buffer->interface->mask; 349 350 TRACE(("demuxing buffer %p as broadcast...\n", buffer)); 351 352 sockaddr anyAddr; 353 sAddressModule->set_to_empty_address(&anyAddr); 354 355 uint16 incomingPort = sAddressModule->get_port(broadcastAddr); 356 357 UdpEndpoint *endpoint; 358 sockaddr *addr, *connectAddr; 359 struct hash_iterator endpointIterator; 360 for(hash_open(fActiveEndpoints, &endpointIterator); ; ) { 361 endpoint = (UdpEndpoint *)hash_next(fActiveEndpoints, &endpointIterator); 362 if (!endpoint) 363 break; 364 365 addr = (sockaddr *)&endpoint->socket->address; 366 TRACE(("UDP-DemuxBroadcast() is checking endpoint %s...\n", 367 AddressString(sDomain, addr, true).Data())); 368 369 if (incomingPort != sAddressModule->get_port(addr)) { 370 // ports don't match, so we do not dispatch to this endpoint... 371 continue; 372 } 373 374 connectAddr = (sockaddr *)&endpoint->socket->peer; 375 if (!sAddressModule->is_empty_address(connectAddr)) { 376 // endpoint is connected to a specific destination, we check if 377 // this datagram is from there: 378 if (!sAddressModule->equal_addresses_and_ports(connectAddr, peerAddr)) { 379 // no, datagram is from another peer, so we do not dispatch to 380 // this endpoint... 381 continue; 382 } 383 } 384 385 if (sAddressModule->equal_masked_addresses(addr, broadcastAddr, mask) 386 || sAddressModule->equal_addresses(addr, &anyAddr)) { 387 // address matches, dispatch to this endpoint: 388 endpoint->StoreData(buffer); 389 } 390 } 391 hash_close(fActiveEndpoints, &endpointIterator, false); 392 return B_OK; 393 } 394 395 396 status_t 397 UdpEndpointManager::DemuxMulticast(net_buffer *buffer) 398 { // TODO: implement! 399 return B_ERROR; 400 } 401 402 403 status_t 404 UdpEndpointManager::DemuxUnicast(net_buffer *buffer) 405 { 406 struct sockaddr *peerAddr = (struct sockaddr *)&buffer->source; 407 struct sockaddr *localAddr = (struct sockaddr *)&buffer->destination; 408 409 TRACE(("demuxing buffer %p as unicast...\n", buffer)); 410 411 struct sockaddr anyAddr; 412 sAddressModule->set_to_empty_address(&anyAddr); 413 414 UdpEndpoint *endpoint; 415 // look for full (most special) match: 416 endpoint = FindActiveEndpoint(localAddr, peerAddr); 417 if (!endpoint) { 418 // look for endpoint matching local address & port: 419 endpoint = FindActiveEndpoint(localAddr, &anyAddr); 420 if (!endpoint) { 421 // look for endpoint matching peer address & port and local port: 422 sockaddr localPortAddr; 423 sAddressModule->set_to_empty_address(&localPortAddr); 424 uint16 localPort = sAddressModule->get_port(localAddr); 425 sAddressModule->set_port(&localPortAddr, localPort); 426 endpoint = FindActiveEndpoint(&localPortAddr, peerAddr); 427 if (!endpoint) { 428 // last chance: look for endpoint matching local port only: 429 endpoint = FindActiveEndpoint(&localPortAddr, &anyAddr); 430 } 431 } 432 } 433 if (!endpoint) 434 return B_NAME_NOT_FOUND; 435 436 endpoint->StoreData(buffer); 437 return B_OK; 438 } 439 440 441 status_t 442 UdpEndpointManager::DemuxIncomingBuffer(net_buffer *buffer) 443 { 444 status_t status; 445 446 if (buffer->flags & MSG_BCAST) 447 status = DemuxBroadcast(buffer); 448 else if (buffer->flags & MSG_MCAST) 449 status = DemuxMulticast(buffer); 450 else 451 status = DemuxUnicast(buffer); 452 453 return status; 454 } 455 456 457 status_t 458 UdpEndpointManager::ReceiveData(net_buffer *buffer) 459 { 460 NetBufferHeader<udp_header> bufferHeader(buffer); 461 if (bufferHeader.Status() < B_OK) 462 return bufferHeader.Status(); 463 464 udp_header &header = bufferHeader.Data(); 465 466 struct sockaddr *source = (struct sockaddr *)&buffer->source; 467 struct sockaddr *destination = (struct sockaddr *)&buffer->destination; 468 469 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 470 if (!sDomain) { 471 // domain and address module are not known yet, we copy them from 472 // the buffer's interface (if any): 473 if (buffer->interface == NULL || buffer->interface->domain == NULL) 474 sDomain = sStackModule->get_domain(AF_INET); 475 else 476 sDomain = buffer->interface->domain; 477 if (sDomain == NULL) { 478 // this shouldn't occur, of course, but who knows... 479 return B_BAD_VALUE; 480 } 481 sAddressModule = sDomain->address_module; 482 } 483 sAddressModule->set_port(source, header.source_port); 484 sAddressModule->set_port(destination, header.destination_port); 485 TRACE(("UDP received data from source %s for destination %s\n", 486 AddressString(sDomain, source, true).Data(), 487 AddressString(sDomain, destination, true).Data())); 488 489 uint16 udpLength = ntohs(header.udp_length); 490 if (udpLength > buffer->size) { 491 TRACE(("buffer %p is too short (%lu instead of %u), we drop it!\n", 492 buffer, buffer->size, udpLength)); 493 return B_MISMATCHED_VALUES; 494 } 495 if (buffer->size > udpLength) { 496 TRACE(("buffer %p is too long (%lu instead of %u), trimming it.\n", 497 buffer, buffer->size, udpLength)); 498 sBufferModule->trim(buffer, udpLength); 499 } 500 501 if (header.udp_checksum != 0) { 502 // check UDP-checksum (simulating a so-called "pseudo-header"): 503 Checksum udpChecksum; 504 sAddressModule->checksum_address(&udpChecksum, source); 505 sAddressModule->checksum_address(&udpChecksum, destination); 506 udpChecksum 507 << (uint16)htons(IPPROTO_UDP) 508 << header.udp_length 509 // peculiar but correct: UDP-len is used twice for checksum 510 // (as it is already contained in udp_header) 511 << Checksum::BufferHelper(buffer, sBufferModule); 512 uint16 sum = udpChecksum; 513 if (sum != 0) { 514 TRACE(("buffer %p has bad checksum (%u), we drop it!\n", buffer, sum)); 515 return B_BAD_VALUE; 516 } 517 } 518 519 bufferHeader.Remove(); 520 // remove UDP-header from buffer before passing it on 521 522 status_t status = DemuxIncomingBuffer(buffer); 523 if (status < B_OK) { 524 TRACE(("no matching endpoint found for buffer %p, we drop it!", buffer)); 525 // TODO: send ICMP-error 526 return B_ERROR; 527 } 528 529 return B_ERROR; 530 } 531 532 533 // #pragma mark - activation 534 535 536 status_t 537 UdpEndpointManager::CheckBindRequest(sockaddr *address, int socketOptions) 538 { // sUdpEndpointManager->Locker() must be locked! 539 status_t status = B_OK; 540 UdpEndpoint *otherEndpoint; 541 sockaddr *otherAddr; 542 struct hash_iterator endpointIterator; 543 544 // Iterate over all active UDP-endpoints and check if the requested bind 545 // is allowed (see figure 22.24 in [Stevens - TCP2, p735]): 546 hash_open(fActiveEndpoints, &endpointIterator); 547 TRACE(("UdpEndpointManager::CheckBindRequest() for %s...\n", 548 AddressString(sDomain, address, true).Data())); 549 while(1) { 550 otherEndpoint = (UdpEndpoint *)hash_next(fActiveEndpoints, &endpointIterator); 551 if (!otherEndpoint) 552 break; 553 otherAddr = (sockaddr *)&otherEndpoint->socket->address; 554 TRACE(("...checking endpoint %p (port=%u)...\n", otherEndpoint, 555 ntohs(sAddressModule->get_port(otherAddr)))); 556 if (sAddressModule->equal_ports(otherAddr, address)) { 557 // port is already bound, SO_REUSEADDR or SO_REUSEPORT is required: 558 if (otherEndpoint->socket->options & (SO_REUSEADDR | SO_REUSEPORT) == 0 559 || socketOptions & (SO_REUSEADDR | SO_REUSEPORT) == 0) { 560 status = EADDRINUSE; 561 break; 562 } 563 // if both addresses are the same, SO_REUSEPORT is required: 564 if (sAddressModule->equal_addresses(otherAddr, address) 565 && (otherEndpoint->socket->options & SO_REUSEPORT == 0 566 || socketOptions & SO_REUSEPORT == 0)) { 567 status = EADDRINUSE; 568 break; 569 } 570 } 571 } 572 hash_close(fActiveEndpoints, &endpointIterator, false); 573 574 TRACE(("UdpEndpointManager::CheckBindRequest done (status=%lx)\n", status)); 575 return status; 576 } 577 578 579 status_t 580 UdpEndpointManager::ActivateEndpoint(UdpEndpoint *endpoint) 581 { // sUdpEndpointManager->Locker() must be locked! 582 TRACE(("UDP-endpoint(%s) is activated\n", 583 AddressString(sDomain, (sockaddr *)&endpoint->socket->address, true).Data())); 584 return hash_insert(fActiveEndpoints, endpoint); 585 } 586 587 588 status_t 589 UdpEndpointManager::DeactivateEndpoint(UdpEndpoint *endpoint) 590 { // sUdpEndpointManager->Locker() must be locked! 591 TRACE(("UDP-endpoint(%s) is deactivated\n", 592 AddressString(sDomain, (sockaddr *)&endpoint->socket->address, true).Data())); 593 return hash_remove(fActiveEndpoints, endpoint); 594 } 595 596 597 status_t 598 UdpEndpointManager::OpenEndpoint(UdpEndpoint *endpoint) 599 { // sUdpEndpointManager->Locker() must be locked! 600 if (fEndpointCount++ == 0) { 601 sDomain = sStackModule->get_domain(AF_INET); 602 sAddressModule = sDomain->address_module; 603 TRACE(("udp: setting domain-pointer to %p.\n", sDomain)); 604 } 605 return B_OK; 606 } 607 608 609 status_t 610 UdpEndpointManager::CloseEndpoint(UdpEndpoint *endpoint) 611 { // sUdpEndpointManager->Locker() must be locked! 612 return B_OK; 613 } 614 615 616 status_t 617 UdpEndpointManager::FreeEndpoint(UdpEndpoint *endpoint) 618 { // sUdpEndpointManager->Locker() must be locked! 619 if (--fEndpointCount == 0) { 620 TRACE(("udp: clearing domain-pointer and address-module.\n")); 621 sDomain = NULL; 622 sAddressModule = NULL; 623 } 624 return B_OK; 625 } 626 627 628 uint16 629 UdpEndpointManager::GetEphemeralPort() 630 { 631 return fEphemerals.GetNext(fActiveEndpoints); 632 } 633 634 635 // #pragma mark - 636 637 638 UdpEndpoint::UdpEndpoint(net_socket *socket) 639 : 640 fActive(false) 641 { 642 status_t status = sStackModule->init_fifo(&fFifo, "UDP endpoint fifo", 643 socket->receive.buffer_size); 644 if (status < B_OK) 645 fFifo.notify = status; 646 } 647 648 649 UdpEndpoint::~UdpEndpoint() 650 { 651 if (fFifo.notify >= B_OK) 652 sStackModule->uninit_fifo(&fFifo); 653 } 654 655 656 // #pragma mark - activation 657 658 659 status_t 660 UdpEndpoint::Bind(sockaddr *address) 661 { 662 if (address->sa_family != AF_INET) 663 return EAFNOSUPPORT; 664 665 // let IP check whether there is an interface that supports the given address: 666 status_t status = next->module->bind(next, address); 667 if (status < B_OK) 668 return status; 669 670 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 671 672 if (fActive) { 673 // socket module should have called unbind() before! 674 return EINVAL; 675 } 676 677 if (sAddressModule->get_port(address) == 0) { 678 uint16 port = htons(sUdpEndpointManager->GetEphemeralPort()); 679 if (port == 0) 680 return ENOBUFS; 681 // whoa, no more ephemeral port available!?! 682 sAddressModule->set_port((sockaddr *)&socket->address, port); 683 } else { 684 status = sUdpEndpointManager->CheckBindRequest((sockaddr *)&socket->address, 685 socket->options); 686 if (status < B_OK) 687 return status; 688 } 689 690 return _Activate(); 691 } 692 693 694 status_t 695 UdpEndpoint::Unbind(sockaddr *address) 696 { 697 if (address->sa_family != AF_INET) 698 return EAFNOSUPPORT; 699 700 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 701 702 return _Deactivate(); 703 } 704 705 706 status_t 707 UdpEndpoint::Connect(const sockaddr *address) 708 { 709 if (address->sa_family != AF_INET && address->sa_family != AF_UNSPEC) 710 return EAFNOSUPPORT; 711 712 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 713 714 if (fActive) 715 _Deactivate(); 716 717 if (address->sa_family == AF_UNSPEC) { 718 // [Stevens-UNP1, p226]: specifying AF_UNSPEC requests a "disconnect", 719 // so we reset the peer address: 720 sAddressModule->set_to_empty_address((sockaddr *)&socket->peer); 721 } else 722 sAddressModule->set_to((sockaddr *)&socket->peer, address); 723 724 // we need to activate no matter whether or not we have just disconnected, 725 // as calling connect() always triggers an implicit bind(): 726 return _Activate(); 727 } 728 729 730 status_t 731 UdpEndpoint::Open() 732 { 733 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 734 return sUdpEndpointManager->OpenEndpoint(this); 735 } 736 737 738 status_t 739 UdpEndpoint::Close() 740 { 741 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 742 if (fActive) 743 _Deactivate(); 744 return sUdpEndpointManager->CloseEndpoint(this); 745 } 746 747 748 status_t 749 UdpEndpoint::Free() 750 { 751 BenaphoreLocker locker(sUdpEndpointManager->Locker()); 752 return sUdpEndpointManager->FreeEndpoint(this); 753 } 754 755 756 status_t 757 UdpEndpoint::_Activate() 758 { 759 if (fActive) 760 return B_ERROR; 761 status_t status = sUdpEndpointManager->ActivateEndpoint(this); 762 fActive = (status == B_OK); 763 return status; 764 } 765 766 767 status_t 768 UdpEndpoint::_Deactivate() 769 { 770 if (!fActive) 771 return B_ERROR; 772 status_t status = sUdpEndpointManager->DeactivateEndpoint(this); 773 fActive = false; 774 return status; 775 } 776 777 778 // #pragma mark - outbound 779 780 781 status_t 782 UdpEndpoint::SendData(net_buffer *buffer, net_route *route) 783 { 784 if (buffer->size > socket->send.buffer_size) 785 return EMSGSIZE; 786 787 buffer->protocol = IPPROTO_UDP; 788 789 { // scope for lifetime of bufferHeader 790 791 // add and fill UDP-specific header: 792 NetBufferPrepend<udp_header> bufferHeader(buffer); 793 if (bufferHeader.Status() < B_OK) 794 return bufferHeader.Status(); 795 796 udp_header &header = bufferHeader.Data(); 797 798 header.source_port = sAddressModule->get_port((sockaddr *)&buffer->source); 799 header.destination_port = sAddressModule->get_port( 800 (sockaddr *)&buffer->destination); 801 header.udp_length = htons(buffer->size); 802 // the udp-header is already included in the buffer-size 803 header.udp_checksum = 0; 804 805 // generate UDP-checksum (simulating a so-called "pseudo-header"): 806 Checksum udpChecksum; 807 sAddressModule->checksum_address(&udpChecksum, 808 (sockaddr *)route->interface->address); 809 sAddressModule->checksum_address(&udpChecksum, 810 (sockaddr *)&buffer->destination); 811 udpChecksum 812 << (uint16)htons(IPPROTO_UDP) 813 << (uint16)htons(buffer->size) 814 // peculiar but correct: UDP-len is used twice for checksum 815 // (as it is already contained in udp_header) 816 << Checksum::BufferHelper(buffer, sBufferModule); 817 header.udp_checksum = udpChecksum; 818 if (header.udp_checksum == 0) 819 header.udp_checksum = 0xFFFF; 820 821 TRACE_BLOCK(((char*)&header, sizeof(udp_header), "udp-hdr: ")); 822 } 823 return next->module->send_routed_data(next, route, buffer); 824 } 825 826 827 // #pragma mark - inbound 828 829 830 ssize_t 831 UdpEndpoint::BytesAvailable() 832 { 833 return fFifo.current_bytes; 834 } 835 836 837 status_t 838 UdpEndpoint::FetchData(size_t numBytes, uint32 flags, net_buffer **_buffer) 839 { 840 net_buffer *buffer; 841 AddressString addressString(sDomain, (sockaddr *)&socket->address, true); 842 TRACE(("FetchData() with size=%ld called for endpoint with (%s)\n", 843 numBytes, addressString.Data())); 844 845 status_t status = sStackModule->fifo_dequeue_buffer(&fFifo, flags, 846 socket->receive.timeout, &buffer); 847 TRACE(("Endpoint with (%s) returned from fifo status=%lx\n", 848 addressString.Data(), status)); 849 if (status < B_OK) 850 return status; 851 852 if (numBytes < buffer->size) { 853 // discard any data behind the amount requested 854 sBufferModule->trim(buffer, numBytes); 855 // TODO: we should indicate MSG_TRUNC to application! 856 } 857 858 TRACE(("FetchData() returns buffer with %ld data bytes\n", buffer->size)); 859 *_buffer = buffer; 860 return B_OK; 861 } 862 863 864 status_t 865 UdpEndpoint::StoreData(net_buffer *_buffer) 866 { 867 TRACE(("buffer %p passed to endpoint with (%s)\n", _buffer, 868 AddressString(sDomain, (sockaddr *)&socket->address, true).Data())); 869 net_buffer *buffer = sBufferModule->clone(_buffer, false); 870 if (buffer == NULL) 871 return B_NO_MEMORY; 872 873 status_t status = sStackModule->fifo_enqueue_buffer(&fFifo, buffer); 874 if (status < B_OK) 875 sBufferModule->free(buffer); 876 877 return status; 878 } 879 880 881 // #pragma mark - protocol interface 882 883 884 net_protocol * 885 udp_init_protocol(net_socket *socket) 886 { 887 socket->protocol = IPPROTO_UDP; 888 socket->send.buffer_size = 65535 - 20 - 8; 889 // subtract lengths of IP and UDP headers (NOTE: IP headers could be 890 // larger if IP options are used, but we do not currently care for that) 891 892 UdpEndpoint *endpoint = new (std::nothrow) UdpEndpoint(socket); 893 TRACE(("udp_init_protocol(%p) created endpoint %p\n", socket, endpoint)); 894 return endpoint; 895 } 896 897 898 status_t 899 udp_uninit_protocol(net_protocol *protocol) 900 { 901 TRACE(("udp_uninit_protocol(%p)\n", protocol)); 902 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 903 delete udpEndpoint; 904 return B_OK; 905 } 906 907 908 status_t 909 udp_open(net_protocol *protocol) 910 { 911 TRACE(("udp_open(%p)\n", protocol)); 912 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 913 return udpEndpoint->Open(); 914 } 915 916 917 status_t 918 udp_close(net_protocol *protocol) 919 { 920 TRACE(("udp_close(%p)\n", protocol)); 921 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 922 return udpEndpoint->Close(); 923 } 924 925 926 status_t 927 udp_free(net_protocol *protocol) 928 { 929 TRACE(("udp_free(%p)\n", protocol)); 930 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 931 return udpEndpoint->Free(); 932 } 933 934 935 status_t 936 udp_connect(net_protocol *protocol, const struct sockaddr *address) 937 { 938 TRACE(("udp_connect(%p) on address %s\n", protocol, 939 AddressString(sDomain, address, true).Data())); 940 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 941 return udpEndpoint->Connect(address); 942 } 943 944 945 status_t 946 udp_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) 947 { 948 return EOPNOTSUPP; 949 } 950 951 952 status_t 953 udp_control(net_protocol *protocol, int level, int option, void *value, 954 size_t *_length) 955 { 956 TRACE(("udp_control(%p)\n", protocol)); 957 return protocol->next->module->control(protocol->next, level, option, 958 value, _length); 959 } 960 961 962 status_t 963 udp_bind(net_protocol *protocol, struct sockaddr *address) 964 { 965 TRACE(("udp_bind(%p) on address %s\n", protocol, 966 AddressString(sDomain, address, true).Data())); 967 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 968 return udpEndpoint->Bind(address); 969 } 970 971 972 status_t 973 udp_unbind(net_protocol *protocol, struct sockaddr *address) 974 { 975 TRACE(("udp_unbind(%p) on address %s\n", protocol, 976 AddressString(sDomain, address, true).Data())); 977 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 978 return udpEndpoint->Unbind(address); 979 } 980 981 982 status_t 983 udp_listen(net_protocol *protocol, int count) 984 { 985 return EOPNOTSUPP; 986 } 987 988 989 status_t 990 udp_shutdown(net_protocol *protocol, int direction) 991 { 992 return EOPNOTSUPP; 993 } 994 995 996 status_t 997 udp_send_routed_data(net_protocol *protocol, struct net_route *route, 998 net_buffer *buffer) 999 { 1000 TRACE(("udp_send_routed_data(%p) size=%lu\n", protocol, buffer->size)); 1001 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 1002 return udpEndpoint->SendData(buffer, route); 1003 } 1004 1005 1006 status_t 1007 udp_send_data(net_protocol *protocol, net_buffer *buffer) 1008 { 1009 TRACE(("udp_send_data(%p) size=%lu\n", protocol, buffer->size)); 1010 1011 struct net_route *route = sDatalinkModule->get_route(sDomain, 1012 (sockaddr *)&buffer->destination); 1013 if (route == NULL) 1014 return ENETUNREACH; 1015 1016 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 1017 status_t status = udpEndpoint->SendData(buffer, route); 1018 sDatalinkModule->put_route(sDomain, route); 1019 return status; 1020 } 1021 1022 1023 ssize_t 1024 udp_send_avail(net_protocol *protocol) 1025 { 1026 ssize_t avail = protocol->socket->send.buffer_size; 1027 TRACE(("udp_send_avail(%p) result=%lu\n", protocol, avail)); 1028 return avail; 1029 } 1030 1031 1032 status_t 1033 udp_read_data(net_protocol *protocol, size_t numBytes, uint32 flags, 1034 net_buffer **_buffer) 1035 { 1036 TRACE(("udp_read_data(%p) size=%lu flags=%lx\n", protocol, numBytes, flags)); 1037 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 1038 return udpEndpoint->FetchData(numBytes, flags, _buffer); 1039 } 1040 1041 1042 ssize_t 1043 udp_read_avail(net_protocol *protocol) 1044 { 1045 UdpEndpoint *udpEndpoint = (UdpEndpoint *)protocol; 1046 return udpEndpoint->BytesAvailable(); 1047 } 1048 1049 1050 struct net_domain * 1051 udp_get_domain(net_protocol *protocol) 1052 { 1053 return protocol->next->module->get_domain(protocol->next); 1054 } 1055 1056 1057 size_t 1058 udp_get_mtu(net_protocol *protocol, const struct sockaddr *address) 1059 { 1060 return protocol->next->module->get_mtu(protocol->next, address); 1061 } 1062 1063 1064 status_t 1065 udp_receive_data(net_buffer *buffer) 1066 { 1067 TRACE(("udp_receive_data() size=%lu\n", buffer->size)); 1068 return sUdpEndpointManager->ReceiveData(buffer); 1069 } 1070 1071 1072 status_t 1073 udp_error(uint32 code, net_buffer *data) 1074 { 1075 return B_ERROR; 1076 } 1077 1078 1079 status_t 1080 udp_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, 1081 void *errorData) 1082 { 1083 return B_ERROR; 1084 } 1085 1086 1087 // #pragma mark - module interface 1088 1089 1090 static status_t 1091 init_udp() 1092 { 1093 status_t status; 1094 TRACE(("init_udp()\n")); 1095 1096 status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule); 1097 if (status < B_OK) 1098 return status; 1099 status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&sBufferModule); 1100 if (status < B_OK) 1101 goto err1; 1102 status = get_module(NET_DATALINK_MODULE_NAME, (module_info **)&sDatalinkModule); 1103 if (status < B_OK) 1104 goto err2; 1105 1106 sUdpEndpointManager = new (std::nothrow) UdpEndpointManager; 1107 if (sUdpEndpointManager == NULL) { 1108 status = ENOBUFS; 1109 goto err3; 1110 } 1111 status = sUdpEndpointManager->InitCheck(); 1112 if (status != B_OK) 1113 goto err3; 1114 1115 status = sStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_IP, 1116 "network/protocols/udp/v1", 1117 "network/protocols/ipv4/v1", 1118 NULL); 1119 if (status < B_OK) 1120 goto err4; 1121 status = sStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 1122 "network/protocols/udp/v1", 1123 "network/protocols/ipv4/v1", 1124 NULL); 1125 if (status < B_OK) 1126 goto err4; 1127 1128 status = sStackModule->register_domain_receiving_protocol(AF_INET, IPPROTO_UDP, 1129 "network/protocols/udp/v1"); 1130 if (status < B_OK) 1131 goto err4; 1132 1133 return B_OK; 1134 1135 err4: 1136 delete sUdpEndpointManager; 1137 err3: 1138 put_module(NET_DATALINK_MODULE_NAME); 1139 err2: 1140 put_module(NET_BUFFER_MODULE_NAME); 1141 err1: 1142 put_module(NET_STACK_MODULE_NAME); 1143 1144 TRACE(("init_udp() fails with %lx (%s)\n", status, strerror(status))); 1145 return status; 1146 } 1147 1148 1149 static status_t 1150 uninit_udp() 1151 { 1152 TRACE(("uninit_udp()\n")); 1153 delete sUdpEndpointManager; 1154 put_module(NET_DATALINK_MODULE_NAME); 1155 put_module(NET_BUFFER_MODULE_NAME); 1156 put_module(NET_STACK_MODULE_NAME); 1157 return B_OK; 1158 } 1159 1160 1161 static status_t 1162 udp_std_ops(int32 op, ...) 1163 { 1164 switch (op) { 1165 case B_MODULE_INIT: 1166 return init_udp(); 1167 1168 case B_MODULE_UNINIT: 1169 return uninit_udp(); 1170 1171 default: 1172 return B_ERROR; 1173 } 1174 } 1175 1176 1177 net_protocol_module_info sUDPModule = { 1178 { 1179 "network/protocols/udp/v1", 1180 0, 1181 udp_std_ops 1182 }, 1183 udp_init_protocol, 1184 udp_uninit_protocol, 1185 udp_open, 1186 udp_close, 1187 udp_free, 1188 udp_connect, 1189 udp_accept, 1190 udp_control, 1191 udp_bind, 1192 udp_unbind, 1193 udp_listen, 1194 udp_shutdown, 1195 udp_send_data, 1196 udp_send_routed_data, 1197 udp_send_avail, 1198 udp_read_data, 1199 udp_read_avail, 1200 udp_get_domain, 1201 udp_get_mtu, 1202 udp_receive_data, 1203 udp_error, 1204 udp_error_reply, 1205 }; 1206 1207 module_info *modules[] = { 1208 (module_info *)&sUDPModule, 1209 NULL 1210 }; 1211