Overhauled BNetEndpoint implementation (and BNetAddress, too):
* added NetEndpointTest that exposed a couple of bugs * fixed several bugs in the implementation of BNetEndpoint, some of which kept NetPenguin from working * fixed a couple of constness issues in BNetEndpoint and BNetAddress git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26405 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -27,22 +27,28 @@ class BNetAddress : public BArchivable {
|
|||||||
BNetAddress(in_addr addr, int port = 0);
|
BNetAddress(in_addr addr, int port = 0);
|
||||||
BNetAddress(uint32 addr, int port = 0);
|
BNetAddress(uint32 addr, int port = 0);
|
||||||
BNetAddress(const BNetAddress& other);
|
BNetAddress(const BNetAddress& other);
|
||||||
BNetAddress(const char* hostname, const char* protocol, const char* service);
|
BNetAddress(const char* hostname, const char* protocol,
|
||||||
|
const char* service);
|
||||||
|
|
||||||
BNetAddress& operator=(const BNetAddress&);
|
BNetAddress& operator=(const BNetAddress&);
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck() const;
|
||||||
|
|
||||||
status_t SetTo(const char* hostname, const char* protocol, const char* service);
|
status_t SetTo(const char* hostname, const char* protocol,
|
||||||
|
const char* service);
|
||||||
status_t SetTo(const char* hostname = NULL, unsigned short port = 0);
|
status_t SetTo(const char* hostname = NULL, unsigned short port = 0);
|
||||||
status_t SetTo(const struct sockaddr_in& addr);
|
status_t SetTo(const struct sockaddr_in& addr);
|
||||||
status_t SetTo(in_addr addr, int port = 0);
|
status_t SetTo(in_addr addr, int port = 0);
|
||||||
status_t SetTo(uint32 addr = INADDR_ANY, int port = 0);
|
status_t SetTo(uint32 addr = INADDR_ANY, int port = 0);
|
||||||
|
|
||||||
status_t GetAddr(char* hostname = NULL, unsigned short* port = NULL) const;
|
status_t GetAddr(char* hostname = NULL,
|
||||||
|
unsigned short* port = NULL) const;
|
||||||
status_t GetAddr(struct sockaddr_in& addr) const;
|
status_t GetAddr(struct sockaddr_in& addr) const;
|
||||||
status_t GetAddr(in_addr& addr, unsigned short* port = NULL) const;
|
status_t GetAddr(in_addr& addr, unsigned short* port = NULL) const;
|
||||||
|
|
||||||
|
// TODO: drop this compatibility cruft method after R1
|
||||||
|
status_t InitCheck();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void _ReservedBNetAddressFBCCruft1();
|
virtual void _ReservedBNetAddressFBCCruft1();
|
||||||
virtual void _ReservedBNetAddressFBCCruft2();
|
virtual void _ReservedBNetAddressFBCCruft2();
|
||||||
|
|||||||
@@ -25,18 +25,19 @@ class BNetEndpoint : public BArchivable {
|
|||||||
|
|
||||||
BNetEndpoint& operator=(const BNetEndpoint& other);
|
BNetEndpoint& operator=(const BNetEndpoint& other);
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck() const;
|
||||||
|
|
||||||
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
virtual status_t Archive(BMessage* into, bool deep = true) const;
|
||||||
static BArchivable* Instantiate(BMessage* archive);
|
static BArchivable* Instantiate(BMessage* archive);
|
||||||
|
|
||||||
status_t SetProtocol(int protocol);
|
status_t SetProtocol(int protocol);
|
||||||
int SetOption(int32 option, int32 level, const void* data, unsigned int dataSize);
|
int SetOption(int32 option, int32 level, const void* data,
|
||||||
|
unsigned int dataSize);
|
||||||
int SetNonBlocking(bool on = true);
|
int SetNonBlocking(bool on = true);
|
||||||
int SetReuseAddr(bool on = true);
|
int SetReuseAddr(bool on = true);
|
||||||
|
|
||||||
const BNetAddress& LocalAddr();
|
const BNetAddress& LocalAddr() const;
|
||||||
const BNetAddress& RemoteAddr();
|
const BNetAddress& RemoteAddr() const;
|
||||||
|
|
||||||
int Socket() const;
|
int Socket() const;
|
||||||
|
|
||||||
@@ -71,7 +72,14 @@ class BNetEndpoint : public BArchivable {
|
|||||||
|
|
||||||
virtual bool IsDataPending(bigtime_t timeout = 0);
|
virtual bool IsDataPending(bigtime_t timeout = 0);
|
||||||
|
|
||||||
|
// TODO: drop these compatibility cruft methods after R1
|
||||||
|
status_t InitCheck();
|
||||||
|
const BNetAddress& LocalAddr();
|
||||||
|
const BNetAddress& RemoteAddr();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t _SetupSocket();
|
||||||
|
|
||||||
virtual void _ReservedBNetEndpointFBCCruft1();
|
virtual void _ReservedBNetEndpointFBCCruft1();
|
||||||
virtual void _ReservedBNetEndpointFBCCruft2();
|
virtual void _ReservedBNetEndpointFBCCruft2();
|
||||||
virtual void _ReservedBNetEndpointFBCCruft3();
|
virtual void _ReservedBNetEndpointFBCCruft3();
|
||||||
@@ -79,14 +87,17 @@ class BNetEndpoint : public BArchivable {
|
|||||||
virtual void _ReservedBNetEndpointFBCCruft5();
|
virtual void _ReservedBNetEndpointFBCCruft5();
|
||||||
virtual void _ReservedBNetEndpointFBCCruft6();
|
virtual void _ReservedBNetEndpointFBCCruft6();
|
||||||
|
|
||||||
status_t fInit;
|
status_t fStatus;
|
||||||
|
int fFamily;
|
||||||
|
int fType;
|
||||||
|
int fProtocol;
|
||||||
int fSocket;
|
int fSocket;
|
||||||
bigtime_t fTimeout;
|
bigtime_t fTimeout;
|
||||||
int fLastError;
|
|
||||||
BNetAddress fAddr;
|
BNetAddress fAddr;
|
||||||
BNetAddress fPeer;
|
BNetAddress fPeer;
|
||||||
|
|
||||||
int32 _reserved[18];
|
int32 _reserved[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // H_NETENDPOINT
|
#endif // H_NETENDPOINT
|
||||||
|
|||||||
@@ -241,12 +241,18 @@ status_t BNetAddress::GetAddr( in_addr& addr, unsigned short* port ) const
|
|||||||
* Returns:
|
* Returns:
|
||||||
* B_OK if this instance is initialized, B_ERROR if not.
|
* B_OK if this instance is initialized, B_ERROR if not.
|
||||||
*/
|
*/
|
||||||
status_t BNetAddress::InitCheck( void )
|
status_t BNetAddress::InitCheck( void ) const
|
||||||
{
|
{
|
||||||
return ( fInit == B_OK ) ? B_OK : B_ERROR;
|
return ( fInit == B_OK ) ? B_OK : B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t BNetAddress::InitCheck()
|
||||||
|
{
|
||||||
|
return const_cast<const BNetAddress*>(this)->InitCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Archive
|
/* Archive
|
||||||
*=--------------------------------------------------------------------------=*
|
*=--------------------------------------------------------------------------=*
|
||||||
* Purpose:
|
* Purpose:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
|
* Copyright 2002-2008, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -20,71 +20,87 @@
|
|||||||
|
|
||||||
BNetEndpoint::BNetEndpoint(int type)
|
BNetEndpoint::BNetEndpoint(int type)
|
||||||
:
|
:
|
||||||
fInit(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
|
fFamily(AF_INET),
|
||||||
|
fType(type),
|
||||||
|
fProtocol(0),
|
||||||
fSocket(-1),
|
fSocket(-1),
|
||||||
fTimeout(B_INFINITE_TIMEOUT),
|
fTimeout(B_INFINITE_TIMEOUT)
|
||||||
fLastError(0)
|
|
||||||
{
|
{
|
||||||
if ((fSocket = socket(AF_INET, type, 0)) < 0)
|
_SetupSocket();
|
||||||
fLastError = errno;
|
|
||||||
else
|
|
||||||
fInit = B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BNetEndpoint::BNetEndpoint(int family, int type, int protocol)
|
BNetEndpoint::BNetEndpoint(int family, int type, int protocol)
|
||||||
:
|
:
|
||||||
fInit(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
|
fFamily(family),
|
||||||
|
fType(type),
|
||||||
|
fProtocol(protocol),
|
||||||
fSocket(-1),
|
fSocket(-1),
|
||||||
fTimeout(B_INFINITE_TIMEOUT),
|
fTimeout(B_INFINITE_TIMEOUT)
|
||||||
fLastError(0)
|
|
||||||
{
|
{
|
||||||
if ((fSocket = socket(family, type, protocol)) < 0)
|
_SetupSocket();
|
||||||
fLastError = errno;
|
|
||||||
else
|
|
||||||
fInit = B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BNetEndpoint::BNetEndpoint(BMessage* archive)
|
BNetEndpoint::BNetEndpoint(BMessage* archive)
|
||||||
:
|
:
|
||||||
fInit(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
|
fFamily(AF_INET),
|
||||||
|
fProtocol(0),
|
||||||
fSocket(-1),
|
fSocket(-1),
|
||||||
fTimeout(B_INFINITE_TIMEOUT),
|
fTimeout(B_INFINITE_TIMEOUT)
|
||||||
fLastError(0)
|
|
||||||
{
|
{
|
||||||
// TODO
|
if (!archive)
|
||||||
if (! archive)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BMessage msg;
|
in_addr addr, peer;
|
||||||
if (archive->FindMessage("bnendp_peer", &msg) != B_OK)
|
unsigned short addrPort = 0, peerPort = 0;
|
||||||
return;
|
|
||||||
fPeer = BNetAddress(&msg);
|
|
||||||
|
|
||||||
if (archive->FindMessage("bnendp_addr", &msg) != B_OK)
|
fStatus = archive->FindInt32("_BNetEndpoint_addr_addr",
|
||||||
return;
|
(int32 *)&addr.s_addr);
|
||||||
fAddr = BNetAddress(&msg);
|
if (fStatus == B_OK) {
|
||||||
|
fStatus = archive->FindInt16("_BNetEndpoint_addr_port",
|
||||||
|
(int16 *)&addrPort);
|
||||||
|
if (fStatus == B_OK)
|
||||||
|
fStatus = fAddr.SetTo(addr, addrPort);
|
||||||
|
}
|
||||||
|
|
||||||
fInit = B_OK;
|
fStatus = archive->FindInt32("_BNetEndpoint_peer_addr",
|
||||||
|
(int32 *)&peer.s_addr);
|
||||||
|
if (fStatus == B_OK) {
|
||||||
|
fStatus = archive->FindInt16("_BNetEndpoint_peer_port",
|
||||||
|
(int16 *)&peerPort);
|
||||||
|
if (fStatus == B_OK)
|
||||||
|
fStatus = fPeer.SetTo(peer, peerPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
fStatus = archive->FindInt64("_BNetEndpoint_timeout", (int64 *)&fTimeout);
|
||||||
|
if (fStatus == B_OK)
|
||||||
|
fStatus = archive->FindInt32("_BNetEndpoint_proto", (int32 *)&fType);
|
||||||
|
|
||||||
|
if (fStatus == B_OK)
|
||||||
|
_SetupSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint)
|
BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint)
|
||||||
:
|
:
|
||||||
fInit(endpoint.fInit),
|
fStatus(endpoint.fStatus),
|
||||||
|
fFamily(endpoint.fFamily),
|
||||||
|
fType(endpoint.fType),
|
||||||
|
fProtocol(endpoint.fProtocol),
|
||||||
|
fSocket(-1),
|
||||||
fTimeout(endpoint.fTimeout),
|
fTimeout(endpoint.fTimeout),
|
||||||
fLastError(endpoint.fLastError),
|
|
||||||
fAddr(endpoint.fAddr),
|
fAddr(endpoint.fAddr),
|
||||||
fPeer(endpoint.fPeer)
|
fPeer(endpoint.fPeer)
|
||||||
|
|
||||||
{
|
{
|
||||||
fSocket = -1;
|
|
||||||
if (endpoint.fSocket >= 0) {
|
if (endpoint.fSocket >= 0) {
|
||||||
fSocket = dup(endpoint.fSocket);
|
fSocket = dup(endpoint.fSocket);
|
||||||
if (fSocket < 0) {
|
if (fSocket < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
fInit = B_NO_INIT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,21 +108,24 @@ BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint)
|
|||||||
BNetEndpoint&
|
BNetEndpoint&
|
||||||
BNetEndpoint::operator=(const BNetEndpoint& endpoint)
|
BNetEndpoint::operator=(const BNetEndpoint& endpoint)
|
||||||
{
|
{
|
||||||
|
if (this == &endpoint)
|
||||||
|
return *this;
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
fInit = endpoint.fInit;
|
fStatus = endpoint.fStatus;
|
||||||
|
fFamily = endpoint.fFamily;
|
||||||
|
fType = endpoint.fType;
|
||||||
|
fProtocol = endpoint.fProtocol;
|
||||||
fTimeout = endpoint.fTimeout;
|
fTimeout = endpoint.fTimeout;
|
||||||
fLastError = endpoint.fLastError;
|
|
||||||
fAddr = endpoint.fAddr;
|
fAddr = endpoint.fAddr;
|
||||||
fPeer = endpoint.fPeer;
|
fPeer = endpoint.fPeer;
|
||||||
|
|
||||||
fSocket = -1;
|
fSocket = -1;
|
||||||
if (endpoint.fSocket >= 0) {
|
if (endpoint.fSocket >= 0) {
|
||||||
fSocket = dup(endpoint.fSocket);
|
fSocket = dup(endpoint.fSocket);
|
||||||
if (fSocket < 0) {
|
if (fSocket < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
fInit = B_NO_INIT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -115,6 +134,7 @@ BNetEndpoint::operator=(const BNetEndpoint& endpoint)
|
|||||||
|
|
||||||
BNetEndpoint::~BNetEndpoint()
|
BNetEndpoint::~BNetEndpoint()
|
||||||
{
|
{
|
||||||
|
if (fSocket >= 0)
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,25 +145,38 @@ BNetEndpoint::~BNetEndpoint()
|
|||||||
status_t
|
status_t
|
||||||
BNetEndpoint::Archive(BMessage* into, bool deep) const
|
BNetEndpoint::Archive(BMessage* into, bool deep) const
|
||||||
{
|
{
|
||||||
// TODO
|
if (!into)
|
||||||
if (into == 0)
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (fInit != B_OK)
|
status_t status = BArchivable::Archive(into, deep);
|
||||||
return B_NO_INIT;
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
BMessage msg;
|
in_addr addr, peer;
|
||||||
if (fPeer.Archive(&msg) != B_OK)
|
unsigned short addrPort, peerPort;
|
||||||
return B_ERROR;
|
|
||||||
if (into->AddMessage("bnendp_peer", &msg) != B_OK)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
if (fAddr.Archive(&msg) != B_OK)
|
status = fAddr.GetAddr(addr, &addrPort);
|
||||||
return B_ERROR;
|
if (status == B_OK) {
|
||||||
if (into->AddMessage("bnendp_addr", &msg) != B_OK)
|
status = into->AddInt32("_BNetEndpoint_addr_addr", addr.s_addr);
|
||||||
return B_ERROR;
|
if (status == B_OK)
|
||||||
|
status = into->AddInt16("_BNetEndpoint_addr_port", addrPort);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = fPeer.GetAddr(peer, &peerPort);
|
||||||
|
if (status == B_OK) {
|
||||||
|
status = into->AddInt32("_BNetEndpoint_peer_addr", peer.s_addr);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = into->AddInt16("_BNetEndpoint_peer_port", peerPort);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
status = into->AddInt64("_BNetEndpoint_timeout", fTimeout);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = into->AddInt32("_BNetEndpoint_proto", fType);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -153,7 +186,7 @@ BNetEndpoint::Instantiate(BMessage* archive)
|
|||||||
if (!archive)
|
if (!archive)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!validate_instantiation(archive, "BNetAddress"))
|
if (!validate_instantiation(archive, "BNetEndpoint"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
BNetEndpoint* endpoint = new BNetEndpoint(archive);
|
BNetEndpoint* endpoint = new BNetEndpoint(archive);
|
||||||
@@ -169,9 +202,9 @@ BNetEndpoint::Instantiate(BMessage* archive)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BNetEndpoint::InitCheck()
|
BNetEndpoint::InitCheck() const
|
||||||
{
|
{
|
||||||
return fInit;
|
return fSocket == -1 ? B_NO_INIT : B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,14 +216,14 @@ BNetEndpoint::Socket() const
|
|||||||
|
|
||||||
|
|
||||||
const BNetAddress&
|
const BNetAddress&
|
||||||
BNetEndpoint::LocalAddr()
|
BNetEndpoint::LocalAddr() const
|
||||||
{
|
{
|
||||||
return fAddr;
|
return fAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const BNetAddress&
|
const BNetAddress&
|
||||||
BNetEndpoint::RemoteAddr()
|
BNetEndpoint::RemoteAddr() const
|
||||||
{
|
{
|
||||||
return fPeer;
|
return fPeer;
|
||||||
}
|
}
|
||||||
@@ -200,12 +233,8 @@ status_t
|
|||||||
BNetEndpoint::SetProtocol(int protocol)
|
BNetEndpoint::SetProtocol(int protocol)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
if ((fSocket = socket(AF_INET, protocol, 0)) < 0) {
|
fType = protocol; // sic (protocol is SOCK_DGRAM or SOCK_STREAM)
|
||||||
fLastError = errno;
|
return _SetupSocket();
|
||||||
return fLastError;
|
|
||||||
}
|
|
||||||
fInit = B_OK;
|
|
||||||
return fInit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -213,11 +242,11 @@ int
|
|||||||
BNetEndpoint::SetOption(int32 option, int32 level,
|
BNetEndpoint::SetOption(int32 option, int32 level,
|
||||||
const void* data, unsigned int length)
|
const void* data, unsigned int length)
|
||||||
{
|
{
|
||||||
if (fInit < B_OK)
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
return fInit;
|
return fStatus;
|
||||||
|
|
||||||
if (setsockopt(fSocket, level, option, data, length) < 0) {
|
if (setsockopt(fSocket, level, option, data, length) < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,9 +257,12 @@ BNetEndpoint::SetOption(int32 option, int32 level,
|
|||||||
int
|
int
|
||||||
BNetEndpoint::SetNonBlocking(bool enable)
|
BNetEndpoint::SetNonBlocking(bool enable)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
int flags = fcntl(fSocket, F_GETFL);
|
int flags = fcntl(fSocket, F_GETFL);
|
||||||
if (flags < 0) {
|
if (flags < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +272,7 @@ BNetEndpoint::SetNonBlocking(bool enable)
|
|||||||
flags &= ~O_NONBLOCK;
|
flags &= ~O_NONBLOCK;
|
||||||
|
|
||||||
if (fcntl(fSocket, F_SETFL, flags) < 0) {
|
if (fcntl(fSocket, F_SETFL, flags) < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +283,9 @@ BNetEndpoint::SetNonBlocking(bool enable)
|
|||||||
int
|
int
|
||||||
BNetEndpoint::SetReuseAddr(bool enable)
|
BNetEndpoint::SetReuseAddr(bool enable)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
int onoff = (int) enable;
|
int onoff = (int) enable;
|
||||||
return SetOption(SO_REUSEADDR, SOL_SOCKET, &onoff, sizeof(onoff));
|
return SetOption(SO_REUSEADDR, SOL_SOCKET, &onoff, sizeof(onoff));
|
||||||
}
|
}
|
||||||
@@ -266,14 +301,14 @@ BNetEndpoint::SetTimeout(bigtime_t timeout)
|
|||||||
int
|
int
|
||||||
BNetEndpoint::Error() const
|
BNetEndpoint::Error() const
|
||||||
{
|
{
|
||||||
return fLastError;
|
return (int)fStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
BNetEndpoint::ErrorStr() const
|
BNetEndpoint::ErrorStr() const
|
||||||
{
|
{
|
||||||
return strerror(fLastError);
|
return strerror(fStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,15 +322,15 @@ BNetEndpoint::Close()
|
|||||||
close(fSocket);
|
close(fSocket);
|
||||||
|
|
||||||
fSocket = -1;
|
fSocket = -1;
|
||||||
fInit = B_NO_INIT;
|
fStatus = B_NO_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BNetEndpoint::Bind(const BNetAddress& address)
|
BNetEndpoint::Bind(const BNetAddress& address)
|
||||||
{
|
{
|
||||||
if (fInit < B_OK)
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
return fInit;
|
return fStatus;
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
status_t status = address.GetAddr(addr);
|
status_t status = address.GetAddr(addr);
|
||||||
@@ -303,28 +338,18 @@ BNetEndpoint::Bind(const BNetAddress& address)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (bind(fSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
if (bind(fSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
Close();
|
Close();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
socklen_t addrSize = sizeof(addr);
|
socklen_t addrSize = sizeof(addr);
|
||||||
if (getsockname(fSocket, (struct sockaddr *)&addr, &addrSize) < 0) {
|
if (getsockname(fSocket, (struct sockaddr *)&addr, &addrSize) < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
Close();
|
Close();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr.sin_addr.s_addr == 0) {
|
|
||||||
// TODO: does this still apply?
|
|
||||||
// Grrr, buggy getsockname!
|
|
||||||
char hostname[MAXHOSTNAMELEN];
|
|
||||||
gethostname(hostname, sizeof(hostname));
|
|
||||||
struct hostent *host = gethostbyname(hostname);
|
|
||||||
if (host != NULL)
|
|
||||||
memcpy(&addr.sin_addr.s_addr, host->h_addr, sizeof(addr.sin_addr.s_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
fAddr.SetTo(addr);
|
fAddr.SetTo(addr);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -341,8 +366,8 @@ BNetEndpoint::Bind(int port)
|
|||||||
status_t
|
status_t
|
||||||
BNetEndpoint::Connect(const BNetAddress& address)
|
BNetEndpoint::Connect(const BNetAddress& address)
|
||||||
{
|
{
|
||||||
if (fInit < B_OK)
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
return fInit;
|
return fStatus;
|
||||||
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
if (address.GetAddr(addr) != B_OK)
|
if (address.GetAddr(addr) != B_OK)
|
||||||
@@ -350,17 +375,16 @@ BNetEndpoint::Connect(const BNetAddress& address)
|
|||||||
|
|
||||||
if (connect(fSocket, (sockaddr *) &addr, sizeof(addr)) < 0) {
|
if (connect(fSocket, (sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
Close();
|
Close();
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
socklen_t addrSize = sizeof(addr);
|
socklen_t addrSize = sizeof(addr);
|
||||||
if (getpeername(fSocket, (sockaddr *) &addr, &addrSize) < 0) {
|
if (getpeername(fSocket, (sockaddr *) &addr, &addrSize) < 0) {
|
||||||
Close();
|
Close();
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fPeer.SetTo(addr);
|
fPeer.SetTo(addr);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -377,12 +401,12 @@ BNetEndpoint::Connect(const char *hostname, int port)
|
|||||||
status_t
|
status_t
|
||||||
BNetEndpoint::Listen(int backlog)
|
BNetEndpoint::Listen(int backlog)
|
||||||
{
|
{
|
||||||
if (fInit < B_OK)
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
return fInit;
|
return fStatus;
|
||||||
|
|
||||||
if (listen(fSocket, backlog) < 0) {
|
if (listen(fSocket, backlog) < 0) {
|
||||||
Close();
|
Close();
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -401,14 +425,14 @@ BNetEndpoint::Accept(int32 timeout)
|
|||||||
int socket = accept(fSocket, (struct sockaddr *) &addr, &addrSize);
|
int socket = accept(fSocket, (struct sockaddr *) &addr, &addrSize);
|
||||||
if (socket < 0) {
|
if (socket < 0) {
|
||||||
Close();
|
Close();
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this);
|
BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this);
|
||||||
if (endpoint == NULL) {
|
if (endpoint == NULL) {
|
||||||
close(socket);
|
close(socket);
|
||||||
fLastError = B_NO_MEMORY;
|
fStatus = B_NO_MEMORY;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +441,7 @@ BNetEndpoint::Accept(int32 timeout)
|
|||||||
|
|
||||||
if (getsockname(socket, (struct sockaddr *)&addr, &addrSize) < 0) {
|
if (getsockname(socket, (struct sockaddr *)&addr, &addrSize) < 0) {
|
||||||
delete endpoint;
|
delete endpoint;
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +468,7 @@ BNetEndpoint::IsDataPending(bigtime_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (select(fSocket + 1, &fds, NULL, NULL, timeout > 0 ? &tv : NULL) < 0) {
|
if (select(fSocket + 1, &fds, NULL, NULL, timeout > 0 ? &tv : NULL) < 0) {
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,12 +479,15 @@ BNetEndpoint::IsDataPending(bigtime_t timeout)
|
|||||||
int32
|
int32
|
||||||
BNetEndpoint::Receive(void* buffer, size_t length, int flags)
|
BNetEndpoint::Receive(void* buffer, size_t length, int flags)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
if (fTimeout >= 0 && IsDataPending(fTimeout) == false)
|
if (fTimeout >= 0 && IsDataPending(fTimeout) == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ssize_t bytesReceived = recv(fSocket, buffer, length, flags);
|
ssize_t bytesReceived = recv(fSocket, buffer, length, flags);
|
||||||
if (bytesReceived < 0)
|
if (bytesReceived < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
|
|
||||||
return bytesReceived;
|
return bytesReceived;
|
||||||
}
|
}
|
||||||
@@ -480,6 +507,9 @@ int32
|
|||||||
BNetEndpoint::ReceiveFrom(void* buffer, size_t length,
|
BNetEndpoint::ReceiveFrom(void* buffer, size_t length,
|
||||||
BNetAddress& address, int flags)
|
BNetAddress& address, int flags)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
if (fTimeout >= 0 && IsDataPending(fTimeout) == false)
|
if (fTimeout >= 0 && IsDataPending(fTimeout) == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -489,7 +519,7 @@ BNetEndpoint::ReceiveFrom(void* buffer, size_t length,
|
|||||||
length = recvfrom(fSocket, buffer, length, flags,
|
length = recvfrom(fSocket, buffer, length, flags,
|
||||||
(struct sockaddr *)&addr, &addrSize);
|
(struct sockaddr *)&addr, &addrSize);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
else
|
else
|
||||||
address.SetTo(addr);
|
address.SetTo(addr);
|
||||||
|
|
||||||
@@ -511,9 +541,12 @@ BNetEndpoint::ReceiveFrom(BNetBuffer& buffer, size_t length,
|
|||||||
int32
|
int32
|
||||||
BNetEndpoint::Send(const void* buffer, size_t length, int flags)
|
BNetEndpoint::Send(const void* buffer, size_t length, int flags)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
ssize_t bytesSent = send(fSocket, (const char *) buffer, length, flags);
|
ssize_t bytesSent = send(fSocket, (const char *) buffer, length, flags);
|
||||||
if (bytesSent < 0)
|
if (bytesSent < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
|
|
||||||
return bytesSent;
|
return bytesSent;
|
||||||
}
|
}
|
||||||
@@ -530,6 +563,9 @@ int32
|
|||||||
BNetEndpoint::SendTo(const void* buffer, size_t length,
|
BNetEndpoint::SendTo(const void* buffer, size_t length,
|
||||||
const BNetAddress& address, int flags)
|
const BNetAddress& address, int flags)
|
||||||
{
|
{
|
||||||
|
if (fSocket < 0 && _SetupSocket() != B_OK)
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
if (address.GetAddr(addr) != B_OK)
|
if (address.GetAddr(addr) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -537,7 +573,7 @@ BNetEndpoint::SendTo(const void* buffer, size_t length,
|
|||||||
ssize_t bytesSent = sendto(fSocket, buffer, length, flags,
|
ssize_t bytesSent = sendto(fSocket, buffer, length, flags,
|
||||||
(struct sockaddr *) &addr, sizeof(addr));
|
(struct sockaddr *) &addr, sizeof(addr));
|
||||||
if (bytesSent < 0)
|
if (bytesSent < 0)
|
||||||
fLastError = errno;
|
fStatus = errno;
|
||||||
|
|
||||||
return bytesSent;
|
return bytesSent;
|
||||||
}
|
}
|
||||||
@@ -554,6 +590,40 @@ BNetEndpoint::SendTo(BNetBuffer& buffer,
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetEndpoint::_SetupSocket()
|
||||||
|
{
|
||||||
|
if ((fSocket = socket(fFamily, fType, fProtocol)) < 0)
|
||||||
|
fStatus = errno;
|
||||||
|
else
|
||||||
|
fStatus = B_OK;
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
status_t BNetEndpoint::InitCheck()
|
||||||
|
{
|
||||||
|
return const_cast<const BNetEndpoint*>(this)->InitCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BNetAddress& BNetEndpoint::LocalAddr()
|
||||||
|
{
|
||||||
|
return const_cast<const BNetEndpoint*>(this)->LocalAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BNetAddress& BNetEndpoint::RemoteAddr()
|
||||||
|
{
|
||||||
|
return const_cast<const BNetEndpoint*>(this)->RemoteAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
// These are virtuals, implemented for binary compatibility purpose
|
// These are virtuals, implemented for binary compatibility purpose
|
||||||
void BNetEndpoint::_ReservedBNetEndpointFBCCruft1() {}
|
void BNetEndpoint::_ReservedBNetEndpointFBCCruft1() {}
|
||||||
void BNetEndpoint::_ReservedBNetEndpointFBCCruft2() {}
|
void BNetEndpoint::_ReservedBNetEndpointFBCCruft2() {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
|
* Copyright 2002-2008, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ SimpleTest tcp_connection_test : tcp_connection_test.cpp
|
|||||||
SimpleTest NetAddressTest : NetAddressTest.cpp
|
SimpleTest NetAddressTest : NetAddressTest.cpp
|
||||||
: $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) ;
|
: $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) ;
|
||||||
|
|
||||||
|
SimpleTest NetEndpointTest : NetEndpointTest.cpp
|
||||||
|
: $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) be ;
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src tests kits net DialUpPreflet ;
|
SubInclude HAIKU_TOP src tests kits net DialUpPreflet ;
|
||||||
SubInclude HAIKU_TOP src tests kits net multicast ;
|
SubInclude HAIKU_TOP src tests kits net multicast ;
|
||||||
SubInclude HAIKU_TOP src tests kits net netperf ;
|
SubInclude HAIKU_TOP src tests kits net netperf ;
|
||||||
|
|||||||
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Oliver Tappe, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <NetEndpoint.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
|
||||||
|
static BNetAddress serverAddr("127.0.0.1", 1234);
|
||||||
|
static BNetAddress clientAddr("127.0.0.1", 51234);
|
||||||
|
|
||||||
|
|
||||||
|
static int problemCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
checkAddrsAreEqual(const BNetAddress& na1, const BNetAddress& na2,
|
||||||
|
const char* fmt)
|
||||||
|
{
|
||||||
|
in_addr addr1, addr2;
|
||||||
|
unsigned short port1, port2;
|
||||||
|
na1.GetAddr(addr1, &port1);
|
||||||
|
na2.GetAddr(addr2, &port2);
|
||||||
|
if (addr1.s_addr == addr2.s_addr && port1 == port2)
|
||||||
|
return;
|
||||||
|
fprintf(stderr, fmt, addr1.s_addr, port1, addr2.s_addr, port2);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
checkArchive(const BNetEndpoint ne, int32 protocol,
|
||||||
|
const BNetAddress& localNetAddress, const BNetAddress& remoteNetAddress)
|
||||||
|
{
|
||||||
|
in_addr localAddr, remoteAddr;
|
||||||
|
unsigned short localPort, remotePort;
|
||||||
|
localNetAddress.GetAddr(localAddr, &localPort);
|
||||||
|
remoteNetAddress.GetAddr(remoteAddr, &remotePort);
|
||||||
|
|
||||||
|
BMessage archive(0UL);
|
||||||
|
status_t status = ne.Archive(&archive);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Archive() failed - %lx:%s\n", status,
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
const char* arcClass;
|
||||||
|
if (archive.FindString("class", &arcClass) != B_OK) {
|
||||||
|
fprintf(stderr, "'class' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (strcmp(arcClass, "BNetEndpoint") != 0) {
|
||||||
|
fprintf(stderr, "expected 'class' to be 'BNetEndpoint' - is '%s'\n",
|
||||||
|
arcClass);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ne.LocalAddr().InitCheck() == B_OK) {
|
||||||
|
int32 arcAddr;
|
||||||
|
if (archive.FindInt32("_BNetEndpoint_addr_addr", &arcAddr) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_addr_addr' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((uint32)localAddr.s_addr != (uint32)arcAddr) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"expected '_BNetEndpoint_addr_addr' to be %x - is %x\n",
|
||||||
|
localAddr.s_addr, (unsigned int)arcAddr);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int16 arcPort;
|
||||||
|
if (archive.FindInt16("_BNetEndpoint_addr_port", &arcPort) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_addr_port' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((uint16)localPort != (uint16)arcPort) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"expected '_BNetEndpoint_addr_port' to be %d - is %d\n",
|
||||||
|
localPort, (int)arcPort);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ne.RemoteAddr().InitCheck() == B_OK) {
|
||||||
|
int32 arcAddr;
|
||||||
|
if (archive.FindInt32("_BNetEndpoint_peer_addr", &arcAddr) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_peer_addr' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((uint32)remoteAddr.s_addr != (uint32)arcAddr) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"expected '_BNetEndpoint_peer_addr' to be %x - is %x\n",
|
||||||
|
remoteAddr.s_addr, (unsigned int)arcAddr);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int16 arcPort;
|
||||||
|
if (archive.FindInt16("_BNetEndpoint_peer_port", &arcPort) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_peer_port' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((uint16)remotePort != (uint16)arcPort) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"expected '_BNetEndpoint_peer_port' to be %u - is %u\n",
|
||||||
|
remotePort, (unsigned short)arcPort);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 arcTimeout;
|
||||||
|
if (archive.FindInt64("_BNetEndpoint_timeout", &arcTimeout) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_timeout' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (arcTimeout != B_INFINITE_TIMEOUT) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"expected '_BNetEndpoint_timeout' to be %llu - is %llu\n",
|
||||||
|
B_INFINITE_TIMEOUT, (uint64)arcTimeout);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 arcProtocol;
|
||||||
|
if (archive.FindInt32("_BNetEndpoint_proto", &arcProtocol) != B_OK) {
|
||||||
|
fprintf(stderr, "'_BNetEndpoint_proto' not found in archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (arcProtocol != protocol) {
|
||||||
|
fprintf(stderr, "expected '_BNetEndpoint_proto' to be %d - is %d\n",
|
||||||
|
(int)protocol, (int)arcProtocol);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BNetEndpoint* clone
|
||||||
|
= dynamic_cast<BNetEndpoint *>(BNetEndpoint::Instantiate(&archive));
|
||||||
|
if (!clone) {
|
||||||
|
fprintf(stderr, "unable to instantiate endpoint from archive\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
delete clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testServer(thread_id clientThread)
|
||||||
|
{
|
||||||
|
char buf[1];
|
||||||
|
|
||||||
|
// check simple UDP "connection"
|
||||||
|
BNetEndpoint server(SOCK_DGRAM);
|
||||||
|
for(int i=0; i < 2; ++i) {
|
||||||
|
status_t status = server.Bind(serverAddr);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Bind() failed in testServer - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAddrsAreEqual(server.LocalAddr(), serverAddr,
|
||||||
|
"LocalAddr() doesn't match serverAddr\n");
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
resume_thread(clientThread);
|
||||||
|
|
||||||
|
BNetAddress remoteAddr;
|
||||||
|
status = server.ReceiveFrom(buf, 1, remoteAddr, 0);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "ReceiveFrom() failed in testServer - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[0] != 'U') {
|
||||||
|
fprintf(stderr, "expected to receive %c but got %c\n", 'U', buf[0]);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAddrsAreEqual(remoteAddr, clientAddr,
|
||||||
|
"remoteAddr(%x:%d) doesn't match clientAddr(%x:%d)\n");
|
||||||
|
|
||||||
|
checkArchive(server, SOCK_DGRAM, serverAddr, clientAddr);
|
||||||
|
|
||||||
|
server.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now switch to TCP and try again
|
||||||
|
server.SetProtocol(SOCK_STREAM);
|
||||||
|
status_t status = server.Bind(serverAddr);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Bind() failed in testServer - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAddrsAreEqual(server.LocalAddr(), serverAddr,
|
||||||
|
"LocalAddr() doesn't match serverAddr\n");
|
||||||
|
|
||||||
|
status = server.Listen();
|
||||||
|
BNetEndpoint* acceptedConn = server.Accept();
|
||||||
|
if (acceptedConn == NULL) {
|
||||||
|
fprintf(stderr, "Accept() failed in testServer\n");
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BNetAddress& remoteAddr = acceptedConn->RemoteAddr();
|
||||||
|
checkAddrsAreEqual(remoteAddr, clientAddr,
|
||||||
|
"remoteAddr(%x:%d) doesn't match clientAddr(%x:%d)\n");
|
||||||
|
|
||||||
|
status = acceptedConn->Receive(buf, 1);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "Receive() failed in testServer - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
delete acceptedConn;
|
||||||
|
|
||||||
|
if (buf[0] != 'T') {
|
||||||
|
fprintf(stderr, "expected to receive %c but got %c\n", 'T', buf[0]);
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkArchive(server, SOCK_STREAM, serverAddr, clientAddr);
|
||||||
|
|
||||||
|
server.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32 testClient(void *)
|
||||||
|
{
|
||||||
|
BNetEndpoint client(SOCK_DGRAM);
|
||||||
|
printf("testing udp...\n");
|
||||||
|
for(int i=0; i < 2; ++i) {
|
||||||
|
status_t status = client.Bind(clientAddr);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Bind() failed in testClient - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAddrsAreEqual(client.LocalAddr(), clientAddr,
|
||||||
|
"LocalAddr(%x:%d) doesn't match clientAddr(%x:%d)\n");
|
||||||
|
|
||||||
|
status = client.SendTo("U", 1, serverAddr, 0);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "SendTo() failed in testClient - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkArchive(client, SOCK_DGRAM, clientAddr, serverAddr);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
client.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
printf("testing tcp...\n");
|
||||||
|
// now switch to TCP and try again
|
||||||
|
client.SetProtocol(SOCK_STREAM);
|
||||||
|
status_t status = client.Bind(clientAddr);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Bind() failed in testClient - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAddrsAreEqual(client.LocalAddr(), clientAddr,
|
||||||
|
"LocalAddr(%x:%d) doesn't match clientAddr(%x:%d)\n");
|
||||||
|
|
||||||
|
status = client.Connect(serverAddr);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "Connect() failed in testClient - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
status = client.Send("T", 1);
|
||||||
|
if (status < B_OK) {
|
||||||
|
fprintf(stderr, "Send() failed in testClient - %s\n",
|
||||||
|
strerror(status));
|
||||||
|
problemCount++;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkArchive(client, SOCK_STREAM, clientAddr, serverAddr);
|
||||||
|
|
||||||
|
client.Close();
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, const char* const* argv)
|
||||||
|
{
|
||||||
|
BNetEndpoint dummy(SOCK_DGRAM);
|
||||||
|
if (sizeof(dummy) != 208) {
|
||||||
|
fprintf(stderr, "expected sizeof(netEndpoint) to be 208 - is %ld\n",
|
||||||
|
sizeof(dummy));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
dummy.Close();
|
||||||
|
|
||||||
|
// start thread for client
|
||||||
|
thread_id tid = spawn_thread(testClient, "client", B_NORMAL_PRIORITY, NULL);
|
||||||
|
if (tid < 0) {
|
||||||
|
fprintf(stderr, "spawn_thread() failed: %s\n", strerror(tid));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
testServer(tid);
|
||||||
|
|
||||||
|
status_t clientStatus;
|
||||||
|
wait_for_thread(tid, &clientStatus);
|
||||||
|
|
||||||
|
if (!problemCount)
|
||||||
|
printf("Everything went fine.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user