1241b0480SAxel Dörfler /* 2*49a22456SOliver Tappe * Copyright 2002-2008, Haiku, Inc. All Rights Reserved. 3241b0480SAxel Dörfler * Distributed under the terms of the MIT License. 4241b0480SAxel Dörfler */ 56fdccb80SAxel Dörfler 66fdccb80SAxel Dörfler #include <Message.h> 76fdccb80SAxel Dörfler #include <NetEndpoint.h> 86fdccb80SAxel Dörfler 9241b0480SAxel Dörfler #include <errno.h> 10241b0480SAxel Dörfler #include <fcntl.h> 11241b0480SAxel Dörfler #include <netdb.h> 12241b0480SAxel Dörfler #include <netinet/in.h> 13241b0480SAxel Dörfler #include <new> 14241b0480SAxel Dörfler #include <string.h> 15241b0480SAxel Dörfler #include <sys/socket.h> 16241b0480SAxel Dörfler #include <sys/time.h> 17241b0480SAxel Dörfler #include <sys/types.h> 18241b0480SAxel Dörfler #include <unistd.h> 196fdccb80SAxel Dörfler 20241b0480SAxel Dörfler 21241b0480SAxel Dörfler BNetEndpoint::BNetEndpoint(int type) 22241b0480SAxel Dörfler : 23*49a22456SOliver Tappe fStatus(B_NO_INIT), 24*49a22456SOliver Tappe fFamily(AF_INET), 25*49a22456SOliver Tappe fType(type), 26*49a22456SOliver Tappe fProtocol(0), 27241b0480SAxel Dörfler fSocket(-1), 28*49a22456SOliver Tappe fTimeout(B_INFINITE_TIMEOUT) 29241b0480SAxel Dörfler { 30*49a22456SOliver Tappe _SetupSocket(); 316fdccb80SAxel Dörfler } 326fdccb80SAxel Dörfler 336fdccb80SAxel Dörfler 346fdccb80SAxel Dörfler BNetEndpoint::BNetEndpoint(int family, int type, int protocol) 35241b0480SAxel Dörfler : 36*49a22456SOliver Tappe fStatus(B_NO_INIT), 37*49a22456SOliver Tappe fFamily(family), 38*49a22456SOliver Tappe fType(type), 39*49a22456SOliver Tappe fProtocol(protocol), 40241b0480SAxel Dörfler fSocket(-1), 41*49a22456SOliver Tappe fTimeout(B_INFINITE_TIMEOUT) 426fdccb80SAxel Dörfler { 43*49a22456SOliver Tappe _SetupSocket(); 446fdccb80SAxel Dörfler } 456fdccb80SAxel Dörfler 466fdccb80SAxel Dörfler 476fdccb80SAxel Dörfler BNetEndpoint::BNetEndpoint(BMessage* archive) 48241b0480SAxel Dörfler : 49*49a22456SOliver Tappe fStatus(B_NO_INIT), 50*49a22456SOliver Tappe fFamily(AF_INET), 51*49a22456SOliver Tappe fProtocol(0), 52241b0480SAxel Dörfler fSocket(-1), 53*49a22456SOliver Tappe fTimeout(B_INFINITE_TIMEOUT) 546fdccb80SAxel Dörfler { 556fdccb80SAxel Dörfler if (!archive) 566fdccb80SAxel Dörfler return; 576fdccb80SAxel Dörfler 58*49a22456SOliver Tappe in_addr addr, peer; 59*49a22456SOliver Tappe unsigned short addrPort = 0, peerPort = 0; 606fdccb80SAxel Dörfler 61*49a22456SOliver Tappe fStatus = archive->FindInt32("_BNetEndpoint_addr_addr", 62*49a22456SOliver Tappe (int32 *)&addr.s_addr); 63*49a22456SOliver Tappe if (fStatus == B_OK) { 64*49a22456SOliver Tappe fStatus = archive->FindInt16("_BNetEndpoint_addr_port", 65*49a22456SOliver Tappe (int16 *)&addrPort); 66*49a22456SOliver Tappe if (fStatus == B_OK) 67*49a22456SOliver Tappe fStatus = fAddr.SetTo(addr, addrPort); 68*49a22456SOliver Tappe } 696fdccb80SAxel Dörfler 70*49a22456SOliver Tappe fStatus = archive->FindInt32("_BNetEndpoint_peer_addr", 71*49a22456SOliver Tappe (int32 *)&peer.s_addr); 72*49a22456SOliver Tappe if (fStatus == B_OK) { 73*49a22456SOliver Tappe fStatus = archive->FindInt16("_BNetEndpoint_peer_port", 74*49a22456SOliver Tappe (int16 *)&peerPort); 75*49a22456SOliver Tappe if (fStatus == B_OK) 76*49a22456SOliver Tappe fStatus = fPeer.SetTo(peer, peerPort); 77*49a22456SOliver Tappe } 78*49a22456SOliver Tappe 79*49a22456SOliver Tappe fStatus = archive->FindInt64("_BNetEndpoint_timeout", (int64 *)&fTimeout); 80*49a22456SOliver Tappe if (fStatus == B_OK) 81*49a22456SOliver Tappe fStatus = archive->FindInt32("_BNetEndpoint_proto", (int32 *)&fType); 82*49a22456SOliver Tappe 83*49a22456SOliver Tappe if (fStatus == B_OK) 84*49a22456SOliver Tappe _SetupSocket(); 856fdccb80SAxel Dörfler } 866fdccb80SAxel Dörfler 876fdccb80SAxel Dörfler 88241b0480SAxel Dörfler BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint) 89241b0480SAxel Dörfler : 90*49a22456SOliver Tappe fStatus(endpoint.fStatus), 91*49a22456SOliver Tappe fFamily(endpoint.fFamily), 92*49a22456SOliver Tappe fType(endpoint.fType), 93*49a22456SOliver Tappe fProtocol(endpoint.fProtocol), 94*49a22456SOliver Tappe fSocket(-1), 95241b0480SAxel Dörfler fTimeout(endpoint.fTimeout), 96241b0480SAxel Dörfler fAddr(endpoint.fAddr), 97241b0480SAxel Dörfler fPeer(endpoint.fPeer) 98*49a22456SOliver Tappe 996fdccb80SAxel Dörfler { 100241b0480SAxel Dörfler if (endpoint.fSocket >= 0) { 101241b0480SAxel Dörfler fSocket = dup(endpoint.fSocket); 102*49a22456SOliver Tappe if (fSocket < 0) 103*49a22456SOliver Tappe fStatus = errno; 104241b0480SAxel Dörfler } 1056fdccb80SAxel Dörfler } 1066fdccb80SAxel Dörfler 1076fdccb80SAxel Dörfler 108241b0480SAxel Dörfler BNetEndpoint& 109241b0480SAxel Dörfler BNetEndpoint::operator=(const BNetEndpoint& endpoint) 1106fdccb80SAxel Dörfler { 111*49a22456SOliver Tappe if (this == &endpoint) 112*49a22456SOliver Tappe return *this; 113*49a22456SOliver Tappe 1146fdccb80SAxel Dörfler Close(); 1156fdccb80SAxel Dörfler 116*49a22456SOliver Tappe fStatus = endpoint.fStatus; 117*49a22456SOliver Tappe fFamily = endpoint.fFamily; 118*49a22456SOliver Tappe fType = endpoint.fType; 119*49a22456SOliver Tappe fProtocol = endpoint.fProtocol; 120241b0480SAxel Dörfler fTimeout = endpoint.fTimeout; 121241b0480SAxel Dörfler fAddr = endpoint.fAddr; 122241b0480SAxel Dörfler fPeer = endpoint.fPeer; 1236fdccb80SAxel Dörfler 124241b0480SAxel Dörfler fSocket = -1; 125241b0480SAxel Dörfler if (endpoint.fSocket >= 0) { 126241b0480SAxel Dörfler fSocket = dup(endpoint.fSocket); 127*49a22456SOliver Tappe if (fSocket < 0) 128*49a22456SOliver Tappe fStatus = errno; 129241b0480SAxel Dörfler } 1306fdccb80SAxel Dörfler 1316fdccb80SAxel Dörfler return *this; 1326fdccb80SAxel Dörfler } 1336fdccb80SAxel Dörfler 134241b0480SAxel Dörfler 1356fdccb80SAxel Dörfler BNetEndpoint::~BNetEndpoint() 1366fdccb80SAxel Dörfler { 137*49a22456SOliver Tappe if (fSocket >= 0) 1386fdccb80SAxel Dörfler Close(); 1396fdccb80SAxel Dörfler } 1406fdccb80SAxel Dörfler 141241b0480SAxel Dörfler 1426fdccb80SAxel Dörfler // #pragma mark - 1436fdccb80SAxel Dörfler 144241b0480SAxel Dörfler 145241b0480SAxel Dörfler status_t 146241b0480SAxel Dörfler BNetEndpoint::Archive(BMessage* into, bool deep) const 1476fdccb80SAxel Dörfler { 148*49a22456SOliver Tappe if (!into) 1496fdccb80SAxel Dörfler return B_ERROR; 1506fdccb80SAxel Dörfler 151*49a22456SOliver Tappe status_t status = BArchivable::Archive(into, deep); 152*49a22456SOliver Tappe if (status != B_OK) 153*49a22456SOliver Tappe return status; 1546fdccb80SAxel Dörfler 155*49a22456SOliver Tappe in_addr addr, peer; 156*49a22456SOliver Tappe unsigned short addrPort, peerPort; 1576fdccb80SAxel Dörfler 158*49a22456SOliver Tappe status = fAddr.GetAddr(addr, &addrPort); 159*49a22456SOliver Tappe if (status == B_OK) { 160*49a22456SOliver Tappe status = into->AddInt32("_BNetEndpoint_addr_addr", addr.s_addr); 161*49a22456SOliver Tappe if (status == B_OK) 162*49a22456SOliver Tappe status = into->AddInt16("_BNetEndpoint_addr_port", addrPort); 163*49a22456SOliver Tappe if (status != B_OK) 164*49a22456SOliver Tappe return status; 165*49a22456SOliver Tappe } 166*49a22456SOliver Tappe status = fPeer.GetAddr(peer, &peerPort); 167*49a22456SOliver Tappe if (status == B_OK) { 168*49a22456SOliver Tappe status = into->AddInt32("_BNetEndpoint_peer_addr", peer.s_addr); 169*49a22456SOliver Tappe if (status == B_OK) 170*49a22456SOliver Tappe status = into->AddInt16("_BNetEndpoint_peer_port", peerPort); 171*49a22456SOliver Tappe if (status != B_OK) 172*49a22456SOliver Tappe return status; 173*49a22456SOliver Tappe } 1746fdccb80SAxel Dörfler 175*49a22456SOliver Tappe status = into->AddInt64("_BNetEndpoint_timeout", fTimeout); 176*49a22456SOliver Tappe if (status == B_OK) 177*49a22456SOliver Tappe status = into->AddInt32("_BNetEndpoint_proto", fType); 178*49a22456SOliver Tappe 179*49a22456SOliver Tappe return status; 1806fdccb80SAxel Dörfler } 1816fdccb80SAxel Dörfler 1826fdccb80SAxel Dörfler 183241b0480SAxel Dörfler BArchivable* 184241b0480SAxel Dörfler BNetEndpoint::Instantiate(BMessage* archive) 1856fdccb80SAxel Dörfler { 1866fdccb80SAxel Dörfler if (!archive) 1876fdccb80SAxel Dörfler return NULL; 1886fdccb80SAxel Dörfler 189*49a22456SOliver Tappe if (!validate_instantiation(archive, "BNetEndpoint")) 1906fdccb80SAxel Dörfler return NULL; 1916fdccb80SAxel Dörfler 192241b0480SAxel Dörfler BNetEndpoint* endpoint = new BNetEndpoint(archive); 193241b0480SAxel Dörfler if (endpoint && endpoint->InitCheck() == B_OK) 194241b0480SAxel Dörfler return endpoint; 1956fdccb80SAxel Dörfler 196241b0480SAxel Dörfler delete endpoint; 1976fdccb80SAxel Dörfler return NULL; 1986fdccb80SAxel Dörfler } 1996fdccb80SAxel Dörfler 200241b0480SAxel Dörfler 2016fdccb80SAxel Dörfler // #pragma mark - 2026fdccb80SAxel Dörfler 2036fdccb80SAxel Dörfler 204241b0480SAxel Dörfler status_t 205*49a22456SOliver Tappe BNetEndpoint::InitCheck() const 2066fdccb80SAxel Dörfler { 207*49a22456SOliver Tappe return fSocket == -1 ? B_NO_INIT : B_OK; 2086fdccb80SAxel Dörfler } 2096fdccb80SAxel Dörfler 2106fdccb80SAxel Dörfler 211241b0480SAxel Dörfler int 212241b0480SAxel Dörfler BNetEndpoint::Socket() const 2136fdccb80SAxel Dörfler { 214241b0480SAxel Dörfler return fSocket; 2156fdccb80SAxel Dörfler } 2166fdccb80SAxel Dörfler 2176fdccb80SAxel Dörfler 218241b0480SAxel Dörfler const BNetAddress& 219*49a22456SOliver Tappe BNetEndpoint::LocalAddr() const 2206fdccb80SAxel Dörfler { 221241b0480SAxel Dörfler return fAddr; 2226fdccb80SAxel Dörfler } 2236fdccb80SAxel Dörfler 2246fdccb80SAxel Dörfler 225241b0480SAxel Dörfler const BNetAddress& 226*49a22456SOliver Tappe BNetEndpoint::RemoteAddr() const 2276fdccb80SAxel Dörfler { 228241b0480SAxel Dörfler return fPeer; 2296fdccb80SAxel Dörfler } 2306fdccb80SAxel Dörfler 2316fdccb80SAxel Dörfler 232241b0480SAxel Dörfler status_t 233241b0480SAxel Dörfler BNetEndpoint::SetProtocol(int protocol) 2346fdccb80SAxel Dörfler { 2356fdccb80SAxel Dörfler Close(); 236*49a22456SOliver Tappe fType = protocol; // sic (protocol is SOCK_DGRAM or SOCK_STREAM) 237*49a22456SOliver Tappe return _SetupSocket(); 2386fdccb80SAxel Dörfler } 2396fdccb80SAxel Dörfler 2406fdccb80SAxel Dörfler 241241b0480SAxel Dörfler int 242241b0480SAxel Dörfler BNetEndpoint::SetOption(int32 option, int32 level, 2436fdccb80SAxel Dörfler const void* data, unsigned int length) 2446fdccb80SAxel Dörfler { 245*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 246*49a22456SOliver Tappe return fStatus; 2476fdccb80SAxel Dörfler 248241b0480SAxel Dörfler if (setsockopt(fSocket, level, option, data, length) < 0) { 249*49a22456SOliver Tappe fStatus = errno; 2506fdccb80SAxel Dörfler return B_ERROR; 2516fdccb80SAxel Dörfler } 252241b0480SAxel Dörfler 2536fdccb80SAxel Dörfler return B_OK; 2546fdccb80SAxel Dörfler } 2556fdccb80SAxel Dörfler 2566fdccb80SAxel Dörfler 257241b0480SAxel Dörfler int 258241b0480SAxel Dörfler BNetEndpoint::SetNonBlocking(bool enable) 2596fdccb80SAxel Dörfler { 260*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 261*49a22456SOliver Tappe return fStatus; 262*49a22456SOliver Tappe 263241b0480SAxel Dörfler int flags = fcntl(fSocket, F_GETFL); 264241b0480SAxel Dörfler if (flags < 0) { 265*49a22456SOliver Tappe fStatus = errno; 266241b0480SAxel Dörfler return B_ERROR; 267241b0480SAxel Dörfler } 2686fdccb80SAxel Dörfler 2696fdccb80SAxel Dörfler if (enable) 2706fdccb80SAxel Dörfler flags |= O_NONBLOCK; 2716fdccb80SAxel Dörfler else 2726fdccb80SAxel Dörfler flags &= ~O_NONBLOCK; 2736fdccb80SAxel Dörfler 274241b0480SAxel Dörfler if (fcntl(fSocket, F_SETFL, flags) < 0) { 275*49a22456SOliver Tappe fStatus = errno; 2766fdccb80SAxel Dörfler return B_ERROR; 2776fdccb80SAxel Dörfler } 2786fdccb80SAxel Dörfler 2796fdccb80SAxel Dörfler return B_OK; 2806fdccb80SAxel Dörfler } 2816fdccb80SAxel Dörfler 2826fdccb80SAxel Dörfler 283241b0480SAxel Dörfler int 284241b0480SAxel Dörfler BNetEndpoint::SetReuseAddr(bool enable) 2856fdccb80SAxel Dörfler { 286*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 287*49a22456SOliver Tappe return fStatus; 288*49a22456SOliver Tappe 2896fdccb80SAxel Dörfler int onoff = (int) enable; 2906fdccb80SAxel Dörfler return SetOption(SO_REUSEADDR, SOL_SOCKET, &onoff, sizeof(onoff)); 2916fdccb80SAxel Dörfler } 2926fdccb80SAxel Dörfler 2936fdccb80SAxel Dörfler 294241b0480SAxel Dörfler void 295241b0480SAxel Dörfler BNetEndpoint::SetTimeout(bigtime_t timeout) 2966fdccb80SAxel Dörfler { 297241b0480SAxel Dörfler fTimeout = timeout; 2986fdccb80SAxel Dörfler } 2996fdccb80SAxel Dörfler 3006fdccb80SAxel Dörfler 301241b0480SAxel Dörfler int 302241b0480SAxel Dörfler BNetEndpoint::Error() const 3036fdccb80SAxel Dörfler { 304*49a22456SOliver Tappe return (int)fStatus; 3056fdccb80SAxel Dörfler } 3066fdccb80SAxel Dörfler 3076fdccb80SAxel Dörfler 308241b0480SAxel Dörfler char* 309241b0480SAxel Dörfler BNetEndpoint::ErrorStr() const 3106fdccb80SAxel Dörfler { 311*49a22456SOliver Tappe return strerror(fStatus); 3126fdccb80SAxel Dörfler } 3136fdccb80SAxel Dörfler 3146fdccb80SAxel Dörfler 3156fdccb80SAxel Dörfler // #pragma mark - 3166fdccb80SAxel Dörfler 317241b0480SAxel Dörfler 318241b0480SAxel Dörfler void 319241b0480SAxel Dörfler BNetEndpoint::Close() 3206fdccb80SAxel Dörfler { 321241b0480SAxel Dörfler if (fSocket >= 0) 322241b0480SAxel Dörfler close(fSocket); 323241b0480SAxel Dörfler 324241b0480SAxel Dörfler fSocket = -1; 325*49a22456SOliver Tappe fStatus = B_NO_INIT; 3266fdccb80SAxel Dörfler } 3276fdccb80SAxel Dörfler 3286fdccb80SAxel Dörfler 329241b0480SAxel Dörfler status_t 330241b0480SAxel Dörfler BNetEndpoint::Bind(const BNetAddress& address) 3316fdccb80SAxel Dörfler { 332*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 333*49a22456SOliver Tappe return fStatus; 3346cde6bebSAxel Dörfler 3356fdccb80SAxel Dörfler struct sockaddr_in addr; 336241b0480SAxel Dörfler status_t status = address.GetAddr(addr); 3376fdccb80SAxel Dörfler if (status != B_OK) 3386fdccb80SAxel Dörfler return status; 3396fdccb80SAxel Dörfler 340241b0480SAxel Dörfler if (bind(fSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 341*49a22456SOliver Tappe fStatus = errno; 3426fdccb80SAxel Dörfler Close(); 3436fdccb80SAxel Dörfler return B_ERROR; 3446fdccb80SAxel Dörfler } 3456fdccb80SAxel Dörfler 346241b0480SAxel Dörfler socklen_t addrSize = sizeof(addr); 347241b0480SAxel Dörfler if (getsockname(fSocket, (struct sockaddr *)&addr, &addrSize) < 0) { 348*49a22456SOliver Tappe fStatus = errno; 3496fdccb80SAxel Dörfler Close(); 3506fdccb80SAxel Dörfler return B_ERROR; 3516fdccb80SAxel Dörfler } 3526fdccb80SAxel Dörfler 353241b0480SAxel Dörfler fAddr.SetTo(addr); 3546fdccb80SAxel Dörfler return B_OK; 3556fdccb80SAxel Dörfler } 3566fdccb80SAxel Dörfler 3576fdccb80SAxel Dörfler 358241b0480SAxel Dörfler status_t 359241b0480SAxel Dörfler BNetEndpoint::Bind(int port) 3606fdccb80SAxel Dörfler { 3616fdccb80SAxel Dörfler BNetAddress addr(INADDR_ANY, port); 3626fdccb80SAxel Dörfler return Bind(addr); 3636fdccb80SAxel Dörfler } 3646fdccb80SAxel Dörfler 3656fdccb80SAxel Dörfler 366241b0480SAxel Dörfler status_t 367241b0480SAxel Dörfler BNetEndpoint::Connect(const BNetAddress& address) 3686fdccb80SAxel Dörfler { 369*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 370*49a22456SOliver Tappe return fStatus; 3716cde6bebSAxel Dörfler 3726fdccb80SAxel Dörfler sockaddr_in addr; 3736fdccb80SAxel Dörfler if (address.GetAddr(addr) != B_OK) 3746fdccb80SAxel Dörfler return B_ERROR; 3756fdccb80SAxel Dörfler 376241b0480SAxel Dörfler if (connect(fSocket, (sockaddr *) &addr, sizeof(addr)) < 0) { 3776fdccb80SAxel Dörfler Close(); 378*49a22456SOliver Tappe fStatus = errno; 3796fdccb80SAxel Dörfler return B_ERROR; 3806fdccb80SAxel Dörfler } 3816fdccb80SAxel Dörfler 382241b0480SAxel Dörfler socklen_t addrSize = sizeof(addr); 383241b0480SAxel Dörfler if (getpeername(fSocket, (sockaddr *) &addr, &addrSize) < 0) { 3846fdccb80SAxel Dörfler Close(); 385*49a22456SOliver Tappe fStatus = errno; 3866fdccb80SAxel Dörfler return B_ERROR; 3876fdccb80SAxel Dörfler } 388241b0480SAxel Dörfler fPeer.SetTo(addr); 3896fdccb80SAxel Dörfler return B_OK; 3906fdccb80SAxel Dörfler } 3916fdccb80SAxel Dörfler 3926fdccb80SAxel Dörfler 393241b0480SAxel Dörfler status_t 394241b0480SAxel Dörfler BNetEndpoint::Connect(const char *hostname, int port) 3956fdccb80SAxel Dörfler { 3966fdccb80SAxel Dörfler BNetAddress addr(hostname, port); 3976fdccb80SAxel Dörfler return Connect(addr); 3986fdccb80SAxel Dörfler } 3996fdccb80SAxel Dörfler 4006fdccb80SAxel Dörfler 401241b0480SAxel Dörfler status_t 402241b0480SAxel Dörfler BNetEndpoint::Listen(int backlog) 4036fdccb80SAxel Dörfler { 404*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 405*49a22456SOliver Tappe return fStatus; 4066cde6bebSAxel Dörfler 407241b0480SAxel Dörfler if (listen(fSocket, backlog) < 0) { 4086fdccb80SAxel Dörfler Close(); 409*49a22456SOliver Tappe fStatus = errno; 4106fdccb80SAxel Dörfler return B_ERROR; 4116fdccb80SAxel Dörfler } 4126fdccb80SAxel Dörfler return B_OK; 4136fdccb80SAxel Dörfler } 4146fdccb80SAxel Dörfler 4156fdccb80SAxel Dörfler 416241b0480SAxel Dörfler BNetEndpoint* 417241b0480SAxel Dörfler BNetEndpoint::Accept(int32 timeout) 4186fdccb80SAxel Dörfler { 4196fdccb80SAxel Dörfler if (!IsDataPending(timeout < 0 ? B_INFINITE_TIMEOUT : 1000LL * timeout)) 4206fdccb80SAxel Dörfler return NULL; 4216fdccb80SAxel Dörfler 4226fdccb80SAxel Dörfler struct sockaddr_in addr; 423241b0480SAxel Dörfler socklen_t addrSize = sizeof(addr); 4246fdccb80SAxel Dörfler 425241b0480SAxel Dörfler int socket = accept(fSocket, (struct sockaddr *) &addr, &addrSize); 426241b0480SAxel Dörfler if (socket < 0) { 4276fdccb80SAxel Dörfler Close(); 428*49a22456SOliver Tappe fStatus = errno; 4296fdccb80SAxel Dörfler return NULL; 4306fdccb80SAxel Dörfler } 4316fdccb80SAxel Dörfler 432241b0480SAxel Dörfler BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this); 433241b0480SAxel Dörfler if (endpoint == NULL) { 434241b0480SAxel Dörfler close(socket); 435*49a22456SOliver Tappe fStatus = B_NO_MEMORY; 4366fdccb80SAxel Dörfler return NULL; 4376fdccb80SAxel Dörfler } 4386fdccb80SAxel Dörfler 439241b0480SAxel Dörfler endpoint->fSocket = socket; 440241b0480SAxel Dörfler endpoint->fPeer.SetTo(addr); 441241b0480SAxel Dörfler 442241b0480SAxel Dörfler if (getsockname(socket, (struct sockaddr *)&addr, &addrSize) < 0) { 443241b0480SAxel Dörfler delete endpoint; 444*49a22456SOliver Tappe fStatus = errno; 4456fdccb80SAxel Dörfler return NULL; 4466fdccb80SAxel Dörfler } 4476fdccb80SAxel Dörfler 448241b0480SAxel Dörfler endpoint->fAddr.SetTo(addr); 449241b0480SAxel Dörfler return endpoint; 4506fdccb80SAxel Dörfler } 4516fdccb80SAxel Dörfler 452241b0480SAxel Dörfler 4536fdccb80SAxel Dörfler // #pragma mark - 4546fdccb80SAxel Dörfler 455241b0480SAxel Dörfler 456241b0480SAxel Dörfler bool 457241b0480SAxel Dörfler BNetEndpoint::IsDataPending(bigtime_t timeout) 4586fdccb80SAxel Dörfler { 459241b0480SAxel Dörfler struct timeval tv; 4606fdccb80SAxel Dörfler fd_set fds; 4616fdccb80SAxel Dörfler 4626fdccb80SAxel Dörfler FD_ZERO(&fds); 463241b0480SAxel Dörfler FD_SET(fSocket, &fds); 4646fdccb80SAxel Dörfler 4656fdccb80SAxel Dörfler if (timeout > 0) { 4666fdccb80SAxel Dörfler tv.tv_sec = timeout / 1000000; 4676fdccb80SAxel Dörfler tv.tv_usec = (timeout % 1000000); 4686fdccb80SAxel Dörfler } 4696fdccb80SAxel Dörfler 470241b0480SAxel Dörfler if (select(fSocket + 1, &fds, NULL, NULL, timeout > 0 ? &tv : NULL) < 0) { 471*49a22456SOliver Tappe fStatus = errno; 4726fdccb80SAxel Dörfler return false; 4736fdccb80SAxel Dörfler } 4746fdccb80SAxel Dörfler 475241b0480SAxel Dörfler return FD_ISSET(fSocket, &fds); 4766fdccb80SAxel Dörfler } 4776fdccb80SAxel Dörfler 4786fdccb80SAxel Dörfler 479241b0480SAxel Dörfler int32 480241b0480SAxel Dörfler BNetEndpoint::Receive(void* buffer, size_t length, int flags) 4816fdccb80SAxel Dörfler { 482*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 483*49a22456SOliver Tappe return fStatus; 484*49a22456SOliver Tappe 485241b0480SAxel Dörfler if (fTimeout >= 0 && IsDataPending(fTimeout) == false) 4866fdccb80SAxel Dörfler return 0; 4876fdccb80SAxel Dörfler 488241b0480SAxel Dörfler ssize_t bytesReceived = recv(fSocket, buffer, length, flags); 489241b0480SAxel Dörfler if (bytesReceived < 0) 490*49a22456SOliver Tappe fStatus = errno; 491241b0480SAxel Dörfler 492241b0480SAxel Dörfler return bytesReceived; 4936fdccb80SAxel Dörfler } 4946fdccb80SAxel Dörfler 4956fdccb80SAxel Dörfler 496241b0480SAxel Dörfler int32 497241b0480SAxel Dörfler BNetEndpoint::Receive(BNetBuffer& buffer, size_t length, int flags) 4986fdccb80SAxel Dörfler { 4996fdccb80SAxel Dörfler BNetBuffer chunk(length); 5006fdccb80SAxel Dörfler length = Receive(chunk.Data(), length, flags); 5016fdccb80SAxel Dörfler buffer.AppendData(chunk.Data(), length); 5026fdccb80SAxel Dörfler return length; 5036fdccb80SAxel Dörfler } 5046fdccb80SAxel Dörfler 5056fdccb80SAxel Dörfler 506241b0480SAxel Dörfler int32 507241b0480SAxel Dörfler BNetEndpoint::ReceiveFrom(void* buffer, size_t length, 5086fdccb80SAxel Dörfler BNetAddress& address, int flags) 5096fdccb80SAxel Dörfler { 510*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 511*49a22456SOliver Tappe return fStatus; 512*49a22456SOliver Tappe 513241b0480SAxel Dörfler if (fTimeout >= 0 && IsDataPending(fTimeout) == false) 5146fdccb80SAxel Dörfler return 0; 5156fdccb80SAxel Dörfler 5166fdccb80SAxel Dörfler struct sockaddr_in addr; 517241b0480SAxel Dörfler socklen_t addrSize = sizeof(addr); 5186fdccb80SAxel Dörfler 519241b0480SAxel Dörfler length = recvfrom(fSocket, buffer, length, flags, 520241b0480SAxel Dörfler (struct sockaddr *)&addr, &addrSize); 5216fdccb80SAxel Dörfler if (length < 0) 522*49a22456SOliver Tappe fStatus = errno; 5236fdccb80SAxel Dörfler else 5246fdccb80SAxel Dörfler address.SetTo(addr); 525241b0480SAxel Dörfler 5266fdccb80SAxel Dörfler return length; 5276fdccb80SAxel Dörfler } 5286fdccb80SAxel Dörfler 5296fdccb80SAxel Dörfler 530241b0480SAxel Dörfler int32 531241b0480SAxel Dörfler BNetEndpoint::ReceiveFrom(BNetBuffer& buffer, size_t length, 5326fdccb80SAxel Dörfler BNetAddress& address, int flags) 5336fdccb80SAxel Dörfler { 5346fdccb80SAxel Dörfler BNetBuffer chunk(length); 5356fdccb80SAxel Dörfler length = ReceiveFrom(chunk.Data(), length, address, flags); 5366fdccb80SAxel Dörfler buffer.AppendData(chunk.Data(), length); 5376fdccb80SAxel Dörfler return length; 5386fdccb80SAxel Dörfler } 5396fdccb80SAxel Dörfler 5406fdccb80SAxel Dörfler 541241b0480SAxel Dörfler int32 542241b0480SAxel Dörfler BNetEndpoint::Send(const void* buffer, size_t length, int flags) 5436fdccb80SAxel Dörfler { 544*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 545*49a22456SOliver Tappe return fStatus; 546*49a22456SOliver Tappe 547241b0480SAxel Dörfler ssize_t bytesSent = send(fSocket, (const char *) buffer, length, flags); 548241b0480SAxel Dörfler if (bytesSent < 0) 549*49a22456SOliver Tappe fStatus = errno; 5506fdccb80SAxel Dörfler 551241b0480SAxel Dörfler return bytesSent; 5526fdccb80SAxel Dörfler } 5536fdccb80SAxel Dörfler 5546fdccb80SAxel Dörfler 555241b0480SAxel Dörfler int32 556241b0480SAxel Dörfler BNetEndpoint::Send(BNetBuffer& buffer, int flags) 5576fdccb80SAxel Dörfler { 5586fdccb80SAxel Dörfler return Send(buffer.Data(), buffer.Size(), flags); 5596fdccb80SAxel Dörfler } 5606fdccb80SAxel Dörfler 5616fdccb80SAxel Dörfler 562241b0480SAxel Dörfler int32 563241b0480SAxel Dörfler BNetEndpoint::SendTo(const void* buffer, size_t length, 5646fdccb80SAxel Dörfler const BNetAddress& address, int flags) 5656fdccb80SAxel Dörfler { 566*49a22456SOliver Tappe if (fSocket < 0 && _SetupSocket() != B_OK) 567*49a22456SOliver Tappe return fStatus; 568*49a22456SOliver Tappe 5696fdccb80SAxel Dörfler struct sockaddr_in addr; 5706fdccb80SAxel Dörfler if (address.GetAddr(addr) != B_OK) 5716fdccb80SAxel Dörfler return B_ERROR; 5726fdccb80SAxel Dörfler 573241b0480SAxel Dörfler ssize_t bytesSent = sendto(fSocket, buffer, length, flags, 5746fdccb80SAxel Dörfler (struct sockaddr *) &addr, sizeof(addr)); 575241b0480SAxel Dörfler if (bytesSent < 0) 576*49a22456SOliver Tappe fStatus = errno; 577241b0480SAxel Dörfler 578241b0480SAxel Dörfler return bytesSent; 5796fdccb80SAxel Dörfler } 5806fdccb80SAxel Dörfler 581241b0480SAxel Dörfler 582241b0480SAxel Dörfler int32 583241b0480SAxel Dörfler BNetEndpoint::SendTo(BNetBuffer& buffer, 5846fdccb80SAxel Dörfler const BNetAddress& address, int flags) 5856fdccb80SAxel Dörfler { 5866fdccb80SAxel Dörfler return SendTo(buffer.Data(), buffer.Size(), address, flags); 5876fdccb80SAxel Dörfler } 5886fdccb80SAxel Dörfler 589241b0480SAxel Dörfler 5906fdccb80SAxel Dörfler // #pragma mark - 5916fdccb80SAxel Dörfler 592241b0480SAxel Dörfler 593*49a22456SOliver Tappe status_t 594*49a22456SOliver Tappe BNetEndpoint::_SetupSocket() 595*49a22456SOliver Tappe { 596*49a22456SOliver Tappe if ((fSocket = socket(fFamily, fType, fProtocol)) < 0) 597*49a22456SOliver Tappe fStatus = errno; 598*49a22456SOliver Tappe else 599*49a22456SOliver Tappe fStatus = B_OK; 600*49a22456SOliver Tappe return fStatus; 601*49a22456SOliver Tappe } 602*49a22456SOliver Tappe 603*49a22456SOliver Tappe 604*49a22456SOliver Tappe // #pragma mark - 605*49a22456SOliver Tappe 606*49a22456SOliver Tappe status_t BNetEndpoint::InitCheck() 607*49a22456SOliver Tappe { 608*49a22456SOliver Tappe return const_cast<const BNetEndpoint*>(this)->InitCheck(); 609*49a22456SOliver Tappe } 610*49a22456SOliver Tappe 611*49a22456SOliver Tappe 612*49a22456SOliver Tappe const BNetAddress& BNetEndpoint::LocalAddr() 613*49a22456SOliver Tappe { 614*49a22456SOliver Tappe return const_cast<const BNetEndpoint*>(this)->LocalAddr(); 615*49a22456SOliver Tappe } 616*49a22456SOliver Tappe 617*49a22456SOliver Tappe 618*49a22456SOliver Tappe const BNetAddress& BNetEndpoint::RemoteAddr() 619*49a22456SOliver Tappe { 620*49a22456SOliver Tappe return const_cast<const BNetEndpoint*>(this)->RemoteAddr(); 621*49a22456SOliver Tappe } 622*49a22456SOliver Tappe 623*49a22456SOliver Tappe 624*49a22456SOliver Tappe // #pragma mark - 625*49a22456SOliver Tappe 626*49a22456SOliver Tappe 6276fdccb80SAxel Dörfler // These are virtuals, implemented for binary compatibility purpose 628241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft1() {} 629241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft2() {} 630241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft3() {} 631241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft4() {} 632241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft5() {} 633241b0480SAxel Dörfler void BNetEndpoint::_ReservedBNetEndpointFBCCruft6() {} 6346fdccb80SAxel Dörfler 635