adapted UDP to use AddressUtilities, for readability.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20850 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-04-27 07:10:11 +00:00
parent c72ab92d84
commit 25a2744f9e
2 changed files with 58 additions and 51 deletions
+20
View File
@@ -52,6 +52,16 @@ public:
return EqualTo(second.fAddress, checkPort); return EqualTo(second.fAddress, checkPort);
} }
bool EqualPorts(const sockaddr *second) const
{
return fModule->equal_ports(fAddress, second);
}
bool MatchMasked(const sockaddr *address, const sockaddr *mask) const
{
return fModule->equal_masked_addresses(fAddress, address, mask);
}
uint16 GetPort() const uint16 GetPort() const
{ {
return fModule->get_port(fAddress); return fModule->get_port(fAddress);
@@ -141,6 +151,16 @@ public:
return fModule->equal_addresses(fAddress, address); return fModule->equal_addresses(fAddress, address);
} }
bool EqualPorts(const sockaddr *second) const
{
return fModule->equal_ports(fAddress, second);
}
bool MatchMasked(const sockaddr *address, const sockaddr *mask) const
{
return fModule->equal_masked_addresses(fAddress, address, mask);
}
uint16 GetPort() const uint16 GetPort() const
{ {
return fModule->get_port(fAddress); return fModule->get_port(fAddress);
@@ -241,7 +241,6 @@ UdpDomainSupport::CheckBindRequest(sockaddr *address, int socketOptions)
{ // sUdpEndpointManager->Locker() must be locked! { // sUdpEndpointManager->Locker() must be locked!
status_t status = B_OK; status_t status = B_OK;
UdpEndpoint *otherEndpoint; UdpEndpoint *otherEndpoint;
sockaddr *otherAddr;
struct hash_iterator endpointIterator; struct hash_iterator endpointIterator;
// Iterate over all active UDP-endpoints and check if the requested bind // Iterate over all active UDP-endpoints and check if the requested bind
@@ -253,18 +252,20 @@ UdpDomainSupport::CheckBindRequest(sockaddr *address, int socketOptions)
otherEndpoint = (UdpEndpoint *)hash_next(fActiveEndpoints, &endpointIterator); otherEndpoint = (UdpEndpoint *)hash_next(fActiveEndpoints, &endpointIterator);
if (!otherEndpoint) if (!otherEndpoint)
break; break;
otherAddr = (sockaddr *)&otherEndpoint->socket->address;
TRACE_DOMAIN(" ...checking endpoint %p (port=%u)...", otherEndpoint, TRACE_DOMAIN(" ...checking endpoint %p (port=%u)...", otherEndpoint,
ntohs(AddressModule()->get_port(otherAddr))); ntohs(otherEndpoint->LocalAddress().GetPort()));
if (AddressModule()->equal_ports(otherAddr, address)) {
if (otherEndpoint->LocalAddress().EqualPorts(address)) {
// port is already bound, SO_REUSEADDR or SO_REUSEPORT is required: // port is already bound, SO_REUSEADDR or SO_REUSEPORT is required:
if (otherEndpoint->socket->options & (SO_REUSEADDR | SO_REUSEPORT) == 0 if (otherEndpoint->socket->options & (SO_REUSEADDR | SO_REUSEPORT) == 0
|| socketOptions & (SO_REUSEADDR | SO_REUSEPORT) == 0) { || socketOptions & (SO_REUSEADDR | SO_REUSEPORT) == 0) {
status = EADDRINUSE; status = EADDRINUSE;
break; break;
} }
// if both addresses are the same, SO_REUSEPORT is required: // if both addresses are the same, SO_REUSEPORT is required:
if (AddressModule()->equal_addresses(otherAddr, address) if (otherEndpoint->LocalAddress().EqualTo(address, false)
&& (otherEndpoint->socket->options & SO_REUSEPORT == 0 && (otherEndpoint->socket->options & SO_REUSEPORT == 0
|| socketOptions & SO_REUSEPORT == 0)) { || socketOptions & SO_REUSEPORT == 0)) {
status = EADDRINUSE; status = EADDRINUSE;
@@ -283,7 +284,7 @@ status_t
UdpDomainSupport::ActivateEndpoint(UdpEndpoint *endpoint) UdpDomainSupport::ActivateEndpoint(UdpEndpoint *endpoint)
{ // sUdpEndpointManager->Locker() must be locked! { // sUdpEndpointManager->Locker() must be locked!
TRACE_DOMAIN("Endpoint(%s) was activated", TRACE_DOMAIN("Endpoint(%s) was activated",
AddressString(fDomain, (sockaddr *)&endpoint->socket->address, true).Data()); AddressString(fDomain, *endpoint->LocalAddress(), true).Data());
return hash_insert(fActiveEndpoints, endpoint); return hash_insert(fActiveEndpoints, endpoint);
} }
@@ -292,7 +293,7 @@ status_t
UdpDomainSupport::DeactivateEndpoint(UdpEndpoint *endpoint) UdpDomainSupport::DeactivateEndpoint(UdpEndpoint *endpoint)
{ // sUdpEndpointManager->Locker() must be locked! { // sUdpEndpointManager->Locker() must be locked!
TRACE_DOMAIN("Endpoint(%s) was deactivated", TRACE_DOMAIN("Endpoint(%s) was deactivated",
AddressString(fDomain, (sockaddr *)&endpoint->socket->address, true).Data()); AddressString(fDomain, *endpoint->LocalAddress(), true).Data());
return hash_remove(fActiveEndpoints, endpoint); return hash_remove(fActiveEndpoints, endpoint);
} }
@@ -335,28 +336,27 @@ UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
hash_open(fActiveEndpoints, &endpointIterator); hash_open(fActiveEndpoints, &endpointIterator);
while ((endpoint = (UdpEndpoint *)hash_next(fActiveEndpoints, while ((endpoint = (UdpEndpoint *)hash_next(fActiveEndpoints,
&endpointIterator)) != NULL) { &endpointIterator)) != NULL) {
sockaddr *addr = (sockaddr *)&endpoint->socket->address;
TRACE_DOMAIN(" _DemuxBroadcast(): checking endpoint %s...",
AddressString(fDomain, addr, true).Data());
if (incomingPort != AddressModule()->get_port(addr)) { TRACE_DOMAIN(" _DemuxBroadcast(): checking endpoint %s...",
AddressString(fDomain, *endpoint->LocalAddress(), true).Data());
if (endpoint->LocalAddress().GetPort() != incomingPort) {
// ports don't match, so we do not dispatch to this endpoint... // ports don't match, so we do not dispatch to this endpoint...
continue; continue;
} }
sockaddr *connectAddr = (sockaddr *)&endpoint->socket->peer; if (!endpoint->PeerAddress().IsEmpty(true)) {
if (!AddressModule()->is_empty_address(connectAddr, true)) {
// endpoint is connected to a specific destination, we check if // endpoint is connected to a specific destination, we check if
// this datagram is from there: // this datagram is from there:
if (!AddressModule()->equal_addresses_and_ports(connectAddr, peerAddr)) { if (!endpoint->PeerAddress().EqualTo(peerAddr, true)) {
// no, datagram is from another peer, so we do not dispatch to // no, datagram is from another peer, so we do not dispatch to
// this endpoint... // this endpoint...
continue; continue;
} }
} }
if (AddressModule()->equal_masked_addresses(addr, broadcastAddr, mask) if (endpoint->LocalAddress().MatchMasked(broadcastAddr, mask)
|| AddressModule()->is_empty_address(addr, false)) { || endpoint->LocalAddress().IsEmpty(false)) {
// address matches, dispatch to this endpoint: // address matches, dispatch to this endpoint:
endpoint->StoreData(buffer); endpoint->StoreData(buffer);
} }
@@ -391,14 +391,13 @@ UdpDomainSupport::_DemuxUnicast(net_buffer *buffer)
endpoint = _FindActiveEndpoint(localAddr, NULL); endpoint = _FindActiveEndpoint(localAddr, NULL);
if (!endpoint) { if (!endpoint) {
// look for endpoint matching peer address & port and local port: // look for endpoint matching peer address & port and local port:
sockaddr localPortAddr; SocketAddressStorage local(AddressModule());
AddressModule()->set_to_empty_address(&localPortAddr); local.SetToEmpty();
uint16 localPort = AddressModule()->get_port(localAddr); local.SetPort(AddressModule()->get_port(localAddr));
AddressModule()->set_port(&localPortAddr, localPort); endpoint = _FindActiveEndpoint(*local, peerAddr);
endpoint = _FindActiveEndpoint(&localPortAddr, peerAddr);
if (!endpoint) { if (!endpoint) {
// last chance: look for endpoint matching local port only: // last chance: look for endpoint matching local port only:
endpoint = _FindActiveEndpoint(&localPortAddr, NULL); endpoint = _FindActiveEndpoint(*local, NULL);
} }
} }
} }
@@ -441,10 +440,12 @@ UdpDomainSupport::_GetNextEphemeral()
found = true; found = true;
break; break;
} }
endpointPort = AddressModule()->get_port(
(sockaddr *)&endpoint->socket->address); endpointPort = endpoint->LocalAddress().GetPort();
TRACE_DOMAIN(" _GetNextEphemeral(): checking endpoint %p (port %hu)...", TRACE_DOMAIN(" _GetNextEphemeral(): checking endpoint %p (port %hu)...",
endpoint, ntohs(endpointPort)); endpoint, ntohs(endpointPort));
if (endpointPort == ncurr) if (endpointPort == ncurr)
break; break;
} }
@@ -470,34 +471,22 @@ UdpDomainSupport::_Compare(void *_udpEndpoint, const void *_key)
struct UdpEndpoint *udpEndpoint = (UdpEndpoint*)_udpEndpoint; struct UdpEndpoint *udpEndpoint = (UdpEndpoint*)_udpEndpoint;
const HashKey *key = (const HashKey *)_key; const HashKey *key = (const HashKey *)_key;
sockaddr *ourAddr = (sockaddr *)&udpEndpoint->socket->address; return (udpEndpoint->LocalAddress().EqualTo(key->local, true)
sockaddr *peerAddr = (sockaddr *)&udpEndpoint->socket->peer; && udpEndpoint->PeerAddress().EqualTo(key->peer, true)) ? 0 : 1;
net_address_module_info *addressModule = key->address_module;
if (addressModule->equal_addresses_and_ports(ourAddr, key->local)
&& addressModule->equal_addresses_and_ports(peerAddr, key->peer))
return 0;
return 1;
} }
uint32 uint32
UdpDomainSupport::_Hash(void *_udpEndpoint, const void *_key, uint32 range) UdpDomainSupport::_Hash(void *_udpEndpoint, const void *_key, uint32 range)
{ {
const UdpEndpoint *udpEndpoint = (const UdpEndpoint *)_udpEndpoint;
const HashKey *key = (const HashKey *)_key; const HashKey *key = (const HashKey *)_key;
HashKey key_storage;
uint32 hash; uint32 hash;
if (_udpEndpoint) { if (udpEndpoint)
const UdpEndpoint *udpEndpoint = (const UdpEndpoint *)_udpEndpoint; hash = udpEndpoint->LocalAddress().HashPair(
key_storage = HashKey(udpEndpoint->DomainSupport()->AddressModule(), *udpEndpoint->PeerAddress());
(const sockaddr *)&udpEndpoint->socket->address, else
(const sockaddr *)&udpEndpoint->socket->peer);
key = &key_storage;
}
hash = key->address_module->hash_address_pair(key->local, key->peer); hash = key->address_module->hash_address_pair(key->local, key->peer);
// move the bits into the relevant range (as defined by kNumHashBuckets): // move the bits into the relevant range (as defined by kNumHashBuckets):
@@ -717,11 +706,9 @@ UdpEndpoint::Bind(const sockaddr *address)
uint16 port = htons(fManager->GetEphemeralPort()); uint16 port = htons(fManager->GetEphemeralPort());
if (port == 0) if (port == 0)
return ENOBUFS; return ENOBUFS;
// whoa, no more ephemeral port available!?! LocalAddress().SetPort(port);
AddressModule()->set_port((sockaddr *)&socket->address, port);
} else { } else {
status = fManager->CheckBindRequest((sockaddr *)&socket->address, status = fManager->CheckBindRequest(*LocalAddress(), socket->options);
socket->options);
if (status < B_OK) if (status < B_OK)
return status; return status;
} }
@@ -754,10 +741,10 @@ UdpEndpoint::Connect(const sockaddr *address)
if (address->sa_family == AF_UNSPEC) { if (address->sa_family == AF_UNSPEC) {
// [Stevens-UNP1, p226]: specifying AF_UNSPEC requests a "disconnect", // [Stevens-UNP1, p226]: specifying AF_UNSPEC requests a "disconnect",
// so we reset the peer address: // so we reset the peer address:
AddressModule()->set_to_empty_address((sockaddr *)&socket->peer); PeerAddress().SetToEmpty();
} else { } else {
// TODO check if `address' is compatible with AddressModule() // TODO check if `address' is compatible with AddressModule()
AddressModule()->set_to((sockaddr *)&socket->peer, address); PeerAddress().SetTo(address);
} }
// we need to activate no matter whether or not we have just disconnected, // we need to activate no matter whether or not we have just disconnected,