1 /* 2 * Copyright 2002-2008, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <Message.h> 7 #include <NetEndpoint.h> 8 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <netdb.h> 12 #include <netinet/in.h> 13 #include <new> 14 #include <string.h> 15 #include <sys/socket.h> 16 #include <sys/time.h> 17 #include <sys/types.h> 18 #include <unistd.h> 19 20 21 BNetEndpoint::BNetEndpoint(int type) 22 : 23 fStatus(B_NO_INIT), 24 fFamily(AF_INET), 25 fType(type), 26 fProtocol(0), 27 fSocket(-1), 28 fTimeout(B_INFINITE_TIMEOUT) 29 { 30 _SetupSocket(); 31 } 32 33 34 BNetEndpoint::BNetEndpoint(int family, int type, int protocol) 35 : 36 fStatus(B_NO_INIT), 37 fFamily(family), 38 fType(type), 39 fProtocol(protocol), 40 fSocket(-1), 41 fTimeout(B_INFINITE_TIMEOUT) 42 { 43 _SetupSocket(); 44 } 45 46 47 BNetEndpoint::BNetEndpoint(BMessage* archive) 48 : 49 fStatus(B_NO_INIT), 50 fFamily(AF_INET), 51 fProtocol(0), 52 fSocket(-1), 53 fTimeout(B_INFINITE_TIMEOUT) 54 { 55 if (!archive) 56 return; 57 58 in_addr addr, peer; 59 unsigned short addrPort = 0, peerPort = 0; 60 61 fStatus = archive->FindInt32("_BNetEndpoint_addr_addr", 62 (int32 *)&addr.s_addr); 63 if (fStatus == B_OK) { 64 fStatus = archive->FindInt16("_BNetEndpoint_addr_port", 65 (int16 *)&addrPort); 66 if (fStatus == B_OK) 67 fStatus = fAddr.SetTo(addr, addrPort); 68 } 69 70 fStatus = archive->FindInt32("_BNetEndpoint_peer_addr", 71 (int32 *)&peer.s_addr); 72 if (fStatus == B_OK) { 73 fStatus = archive->FindInt16("_BNetEndpoint_peer_port", 74 (int16 *)&peerPort); 75 if (fStatus == B_OK) 76 fStatus = fPeer.SetTo(peer, peerPort); 77 } 78 79 fStatus = archive->FindInt64("_BNetEndpoint_timeout", (int64 *)&fTimeout); 80 if (fStatus == B_OK) 81 fStatus = archive->FindInt32("_BNetEndpoint_proto", (int32 *)&fType); 82 83 if (fStatus == B_OK) 84 _SetupSocket(); 85 } 86 87 88 BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint) 89 : 90 fStatus(endpoint.fStatus), 91 fFamily(endpoint.fFamily), 92 fType(endpoint.fType), 93 fProtocol(endpoint.fProtocol), 94 fSocket(-1), 95 fTimeout(endpoint.fTimeout), 96 fAddr(endpoint.fAddr), 97 fPeer(endpoint.fPeer) 98 99 { 100 if (endpoint.fSocket >= 0) { 101 fSocket = dup(endpoint.fSocket); 102 if (fSocket < 0) 103 fStatus = errno; 104 } 105 } 106 107 108 // Private constructor only used from BNetEndpoint::Accept(). 109 BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint, int socket, 110 const struct sockaddr_in& localAddress, 111 const struct sockaddr_in& peerAddress) 112 : 113 fStatus(endpoint.fStatus), 114 fFamily(endpoint.fFamily), 115 fType(endpoint.fType), 116 fProtocol(endpoint.fProtocol), 117 fSocket(socket), 118 fTimeout(endpoint.fTimeout), 119 fAddr(localAddress), 120 fPeer(peerAddress) 121 { 122 } 123 124 125 BNetEndpoint& 126 BNetEndpoint::operator=(const BNetEndpoint& endpoint) 127 { 128 if (this == &endpoint) 129 return *this; 130 131 Close(); 132 133 fStatus = endpoint.fStatus; 134 fFamily = endpoint.fFamily; 135 fType = endpoint.fType; 136 fProtocol = endpoint.fProtocol; 137 fTimeout = endpoint.fTimeout; 138 fAddr = endpoint.fAddr; 139 fPeer = endpoint.fPeer; 140 141 fSocket = -1; 142 if (endpoint.fSocket >= 0) { 143 fSocket = dup(endpoint.fSocket); 144 if (fSocket < 0) 145 fStatus = errno; 146 } 147 148 return *this; 149 } 150 151 152 BNetEndpoint::~BNetEndpoint() 153 { 154 if (fSocket >= 0) 155 Close(); 156 } 157 158 159 // #pragma mark - 160 161 162 status_t 163 BNetEndpoint::Archive(BMessage* into, bool deep) const 164 { 165 if (!into) 166 return B_ERROR; 167 168 status_t status = BArchivable::Archive(into, deep); 169 if (status != B_OK) 170 return status; 171 172 in_addr addr, peer; 173 unsigned short addrPort, peerPort; 174 175 status = fAddr.GetAddr(addr, &addrPort); 176 if (status == B_OK) { 177 status = into->AddInt32("_BNetEndpoint_addr_addr", addr.s_addr); 178 if (status == B_OK) 179 status = into->AddInt16("_BNetEndpoint_addr_port", addrPort); 180 if (status != B_OK) 181 return status; 182 } 183 status = fPeer.GetAddr(peer, &peerPort); 184 if (status == B_OK) { 185 status = into->AddInt32("_BNetEndpoint_peer_addr", peer.s_addr); 186 if (status == B_OK) 187 status = into->AddInt16("_BNetEndpoint_peer_port", peerPort); 188 if (status != B_OK) 189 return status; 190 } 191 192 status = into->AddInt64("_BNetEndpoint_timeout", fTimeout); 193 if (status == B_OK) 194 status = into->AddInt32("_BNetEndpoint_proto", fType); 195 196 return status; 197 } 198 199 200 BArchivable* 201 BNetEndpoint::Instantiate(BMessage* archive) 202 { 203 if (!archive) 204 return NULL; 205 206 if (!validate_instantiation(archive, "BNetEndpoint")) 207 return NULL; 208 209 BNetEndpoint* endpoint = new BNetEndpoint(archive); 210 if (endpoint && endpoint->InitCheck() == B_OK) 211 return endpoint; 212 213 delete endpoint; 214 return NULL; 215 } 216 217 218 // #pragma mark - 219 220 221 status_t 222 BNetEndpoint::InitCheck() const 223 { 224 return fSocket == -1 ? B_NO_INIT : B_OK; 225 } 226 227 228 int 229 BNetEndpoint::Socket() const 230 { 231 return fSocket; 232 } 233 234 235 const BNetAddress& 236 BNetEndpoint::LocalAddr() const 237 { 238 return fAddr; 239 } 240 241 242 const BNetAddress& 243 BNetEndpoint::RemoteAddr() const 244 { 245 return fPeer; 246 } 247 248 249 status_t 250 BNetEndpoint::SetProtocol(int protocol) 251 { 252 Close(); 253 fType = protocol; // sic (protocol is SOCK_DGRAM or SOCK_STREAM) 254 return _SetupSocket(); 255 } 256 257 258 int 259 BNetEndpoint::SetOption(int32 option, int32 level, 260 const void* data, unsigned int length) 261 { 262 if (fSocket < 0 && _SetupSocket() != B_OK) 263 return fStatus; 264 265 if (setsockopt(fSocket, level, option, data, length) < 0) { 266 fStatus = errno; 267 return B_ERROR; 268 } 269 270 return B_OK; 271 } 272 273 274 int 275 BNetEndpoint::SetNonBlocking(bool enable) 276 { 277 if (fSocket < 0 && _SetupSocket() != B_OK) 278 return fStatus; 279 280 int flags = fcntl(fSocket, F_GETFL); 281 if (flags < 0) { 282 fStatus = errno; 283 return B_ERROR; 284 } 285 286 if (enable) 287 flags |= O_NONBLOCK; 288 else 289 flags &= ~O_NONBLOCK; 290 291 if (fcntl(fSocket, F_SETFL, flags) < 0) { 292 fStatus = errno; 293 return B_ERROR; 294 } 295 296 return B_OK; 297 } 298 299 300 int 301 BNetEndpoint::SetReuseAddr(bool enable) 302 { 303 if (fSocket < 0 && _SetupSocket() != B_OK) 304 return fStatus; 305 306 int onoff = (int) enable; 307 return SetOption(SO_REUSEADDR, SOL_SOCKET, &onoff, sizeof(onoff)); 308 } 309 310 311 void 312 BNetEndpoint::SetTimeout(bigtime_t timeout) 313 { 314 fTimeout = timeout; 315 // TODO: Map value < 0 to B_INFINITE_TIMEOUT or use -1 by default. 316 } 317 318 319 int 320 BNetEndpoint::Error() const 321 { 322 return (int)fStatus; 323 } 324 325 326 char* 327 BNetEndpoint::ErrorStr() const 328 { 329 return strerror(fStatus); 330 } 331 332 333 // #pragma mark - 334 335 336 void 337 BNetEndpoint::Close() 338 { 339 if (fSocket >= 0) 340 close(fSocket); 341 342 fSocket = -1; 343 fStatus = B_NO_INIT; 344 } 345 346 347 status_t 348 BNetEndpoint::Bind(const BNetAddress& address) 349 { 350 if (fSocket < 0 && _SetupSocket() != B_OK) 351 return fStatus; 352 353 struct sockaddr_in addr; 354 status_t status = address.GetAddr(addr); 355 if (status != B_OK) 356 return status; 357 358 if (bind(fSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 359 fStatus = errno; 360 Close(); 361 return B_ERROR; 362 } 363 364 socklen_t addrSize = sizeof(addr); 365 if (getsockname(fSocket, (struct sockaddr *)&addr, &addrSize) < 0) { 366 fStatus = errno; 367 Close(); 368 return B_ERROR; 369 } 370 371 fAddr.SetTo(addr); 372 return B_OK; 373 } 374 375 376 status_t 377 BNetEndpoint::Bind(int port) 378 { 379 BNetAddress addr(INADDR_ANY, port); 380 return Bind(addr); 381 } 382 383 384 status_t 385 BNetEndpoint::Connect(const BNetAddress& address) 386 { 387 if (fSocket < 0 && _SetupSocket() != B_OK) 388 return fStatus; 389 390 sockaddr_in addr; 391 if (address.GetAddr(addr) != B_OK) 392 return B_ERROR; 393 394 if (connect(fSocket, (sockaddr *) &addr, sizeof(addr)) < 0) { 395 Close(); 396 fStatus = errno; 397 return B_ERROR; 398 } 399 400 socklen_t addrSize = sizeof(addr); 401 if (getpeername(fSocket, (sockaddr *) &addr, &addrSize) < 0) { 402 Close(); 403 fStatus = errno; 404 return B_ERROR; 405 } 406 fPeer.SetTo(addr); 407 return B_OK; 408 } 409 410 411 status_t 412 BNetEndpoint::Connect(const char *hostname, int port) 413 { 414 BNetAddress addr(hostname, port); 415 return Connect(addr); 416 } 417 418 419 status_t 420 BNetEndpoint::Listen(int backlog) 421 { 422 if (fSocket < 0 && _SetupSocket() != B_OK) 423 return fStatus; 424 425 if (listen(fSocket, backlog) < 0) { 426 Close(); 427 fStatus = errno; 428 return B_ERROR; 429 } 430 return B_OK; 431 } 432 433 434 BNetEndpoint* 435 BNetEndpoint::Accept(int32 timeout) 436 { 437 // TODO: IsDataPending() expects 0 as special value for infinite timeout, 438 // hence the following call is broken for timeout < 0 and timeout == 0. 439 if (!IsDataPending(timeout < 0 ? B_INFINITE_TIMEOUT : 1000LL * timeout)) 440 return NULL; 441 442 struct sockaddr_in peerAddress; 443 socklen_t peerAddressSize = sizeof(peerAddress); 444 445 int socket 446 = accept(fSocket, (struct sockaddr *)&peerAddress, &peerAddressSize); 447 if (socket < 0) { 448 Close(); 449 fStatus = errno; 450 return NULL; 451 } 452 453 struct sockaddr_in localAddress; 454 socklen_t localAddressSize = sizeof(localAddress); 455 if (getsockname(socket, (struct sockaddr *)&localAddress, 456 &localAddressSize) < 0) { 457 close(socket); 458 fStatus = errno; 459 return NULL; 460 } 461 462 BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this, socket, 463 localAddress, peerAddress); 464 if (endpoint == NULL) { 465 close(socket); 466 fStatus = B_NO_MEMORY; 467 return NULL; 468 } 469 470 return endpoint; 471 } 472 473 474 // #pragma mark - 475 476 477 bool 478 BNetEndpoint::IsDataPending(bigtime_t timeout) 479 { 480 struct timeval tv; 481 fd_set fds; 482 483 FD_ZERO(&fds); 484 FD_SET(fSocket, &fds); 485 486 if (timeout > 0) { 487 tv.tv_sec = timeout / 1000000; 488 // TODO: A big value (e.g. B_INFINITE_TIMEOUT) will overflow! 489 tv.tv_usec = (timeout % 1000000); 490 } 491 492 if (select(fSocket + 1, &fds, NULL, NULL, timeout > 0 ? &tv : NULL) < 0) { 493 fStatus = errno; 494 return false; 495 } 496 497 return FD_ISSET(fSocket, &fds); 498 } 499 500 501 int32 502 BNetEndpoint::Receive(void* buffer, size_t length, int flags) 503 { 504 if (fSocket < 0 && _SetupSocket() != B_OK) 505 return fStatus; 506 507 // TODO: For fTimeout == 0 this is broken as IsDataPending(0) means wait 508 // without timeout. Furthermore the default fTimeout is B_INFINITE_TIMEOUT. 509 if (fTimeout >= 0 && IsDataPending(fTimeout) == false) 510 return 0; 511 512 ssize_t bytesReceived = recv(fSocket, buffer, length, flags); 513 if (bytesReceived < 0) 514 fStatus = errno; 515 516 return bytesReceived; 517 } 518 519 520 int32 521 BNetEndpoint::Receive(BNetBuffer& buffer, size_t length, int flags) 522 { 523 BNetBuffer chunk(length); 524 ssize_t bytesReceived = Receive(chunk.Data(), length, flags); 525 if (bytesReceived > 0) 526 buffer.AppendData(chunk.Data(), bytesReceived); 527 return bytesReceived; 528 } 529 530 531 int32 532 BNetEndpoint::ReceiveFrom(void* buffer, size_t length, 533 BNetAddress& address, int flags) 534 { 535 if (fSocket < 0 && _SetupSocket() != B_OK) 536 return fStatus; 537 538 // TODO: For fTimeout == 0 this is broken as IsDataPending(0) means wait 539 // without timeout. Furthermore the default fTimeout is B_INFINITE_TIMEOUT. 540 if (fTimeout >= 0 && IsDataPending(fTimeout) == false) 541 return 0; 542 543 struct sockaddr_in addr; 544 socklen_t addrSize = sizeof(addr); 545 546 ssize_t bytesReceived = recvfrom(fSocket, buffer, length, flags, 547 (struct sockaddr *)&addr, &addrSize); 548 if (bytesReceived < 0) 549 fStatus = errno; 550 else 551 address.SetTo(addr); 552 553 return bytesReceived; 554 } 555 556 557 int32 558 BNetEndpoint::ReceiveFrom(BNetBuffer& buffer, size_t length, 559 BNetAddress& address, int flags) 560 { 561 BNetBuffer chunk(length); 562 ssize_t bytesReceived = ReceiveFrom(chunk.Data(), length, address, flags); 563 if (bytesReceived > 0) 564 buffer.AppendData(chunk.Data(), bytesReceived); 565 return bytesReceived; 566 } 567 568 569 int32 570 BNetEndpoint::Send(const void* buffer, size_t length, int flags) 571 { 572 if (fSocket < 0 && _SetupSocket() != B_OK) 573 return fStatus; 574 575 ssize_t bytesSent = send(fSocket, (const char *) buffer, length, flags); 576 if (bytesSent < 0) 577 fStatus = errno; 578 579 return bytesSent; 580 } 581 582 583 int32 584 BNetEndpoint::Send(BNetBuffer& buffer, int flags) 585 { 586 return Send(buffer.Data(), buffer.Size(), flags); 587 } 588 589 590 int32 591 BNetEndpoint::SendTo(const void* buffer, size_t length, 592 const BNetAddress& address, int flags) 593 { 594 if (fSocket < 0 && _SetupSocket() != B_OK) 595 return fStatus; 596 597 struct sockaddr_in addr; 598 if (address.GetAddr(addr) != B_OK) 599 return B_ERROR; 600 601 ssize_t bytesSent = sendto(fSocket, buffer, length, flags, 602 (struct sockaddr *) &addr, sizeof(addr)); 603 if (bytesSent < 0) 604 fStatus = errno; 605 606 return bytesSent; 607 } 608 609 610 int32 611 BNetEndpoint::SendTo(BNetBuffer& buffer, 612 const BNetAddress& address, int flags) 613 { 614 return SendTo(buffer.Data(), buffer.Size(), address, flags); 615 } 616 617 618 // #pragma mark - 619 620 621 status_t 622 BNetEndpoint::_SetupSocket() 623 { 624 if ((fSocket = socket(fFamily, fType, fProtocol)) < 0) 625 fStatus = errno; 626 else 627 fStatus = B_OK; 628 return fStatus; 629 } 630 631 632 // #pragma mark - 633 634 status_t BNetEndpoint::InitCheck() 635 { 636 return const_cast<const BNetEndpoint*>(this)->InitCheck(); 637 } 638 639 640 const BNetAddress& BNetEndpoint::LocalAddr() 641 { 642 return const_cast<const BNetEndpoint*>(this)->LocalAddr(); 643 } 644 645 646 const BNetAddress& BNetEndpoint::RemoteAddr() 647 { 648 return const_cast<const BNetEndpoint*>(this)->RemoteAddr(); 649 } 650 651 652 // #pragma mark - 653 654 655 // These are virtuals, implemented for binary compatibility purpose 656 void BNetEndpoint::_ReservedBNetEndpointFBCCruft1() {} 657 void BNetEndpoint::_ReservedBNetEndpointFBCCruft2() {} 658 void BNetEndpoint::_ReservedBNetEndpointFBCCruft3() {} 659 void BNetEndpoint::_ReservedBNetEndpointFBCCruft4() {} 660 void BNetEndpoint::_ReservedBNetEndpointFBCCruft5() {} 661 void BNetEndpoint::_ReservedBNetEndpointFBCCruft6() {} 662 663