From 2e1729d050a350918bd974d570a82dfcc57784a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 23 Jul 2010 10:24:19 +0000 Subject: [PATCH] * Removed _EndpointFor() again; DeliverError() is using _FindActiveEndpoint() instead, ie. ICMP errors are only forwarded to connected UDP sockets. * Also notify the DatagramSocket's dequeue loop if an error occurs - this makes udp_unreachable finally work as intended. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37714 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/network/protocols/udp/udp.cpp | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 773657e79d..56f125289e 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -188,7 +188,6 @@ private: UdpEndpoint *_FindActiveEndpoint(const sockaddr *ourAddress, const sockaddr *peerAddress); - UdpEndpoint* _EndpointFor(net_buffer* buffer); status_t _DemuxBroadcast(net_buffer *buffer); status_t _DemuxUnicast(net_buffer *buffer); @@ -303,12 +302,13 @@ UdpDomainSupport::DeliverError(status_t error, net_buffer* buffer) MutexLocker _(fLock); - // RFC 1122 4.1.3.3: - // TODO: Pass to the application layer all ICMP error messages - - UdpEndpoint* endpoint = _EndpointFor(buffer); - if (endpoint != NULL) + // Forward the error to the socket + UdpEndpoint* endpoint = _FindActiveEndpoint(buffer->source, + buffer->destination); + if (endpoint != NULL) { gSocketModule->notify(endpoint->Socket(), B_SELECT_ERROR, error); + endpoint->NotifyOne(); + } gBufferModule->free(buffer); return B_OK; @@ -500,6 +500,8 @@ UdpEndpoint * UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress, const sockaddr *peerAddress) { + ASSERT_LOCKED_MUTEX(&fLock); + TRACE_DOMAIN("finding Endpoint for %s <- %s", AddressString(fDomain, ourAddress, true).Data(), AddressString(fDomain, peerAddress, true).Data()); @@ -508,37 +510,6 @@ UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress, } -UdpEndpoint* -UdpDomainSupport::_EndpointFor(net_buffer* buffer) -{ - ASSERT_LOCKED_MUTEX(&fLock); - - struct sockaddr *peerAddr = buffer->source; - struct sockaddr *localAddr = buffer->destination; - - // look for full (most special) match: - UdpEndpoint* endpoint = _FindActiveEndpoint(localAddr, peerAddr); - if (endpoint != NULL) - return endpoint; - - // look for endpoint matching local address & port: - endpoint = _FindActiveEndpoint(localAddr, NULL); - if (endpoint != NULL) - return endpoint; - - // look for endpoint matching peer address & port and local port: - SocketAddressStorage local(AddressModule()); - local.SetToEmpty(); - local.SetPort(AddressModule()->get_port(localAddr)); - endpoint = _FindActiveEndpoint(*local, peerAddr); - if (endpoint != NULL) - return endpoint; - - // last chance: look for endpoint matching local port only: - return _FindActiveEndpoint(*local, NULL); -} - - status_t UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer) { @@ -587,11 +558,31 @@ UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer) status_t -UdpDomainSupport::_DemuxUnicast(net_buffer *buffer) +UdpDomainSupport::_DemuxUnicast(net_buffer* buffer) { TRACE_DOMAIN("_DemuxUnicast(%p)", buffer); - UdpEndpoint* endpoint = _EndpointFor(buffer); + const sockaddr* localAddress = buffer->destination; + const sockaddr* peerAddress = buffer->source; + + // look for full (most special) match: + UdpEndpoint* endpoint = _FindActiveEndpoint(localAddress, peerAddress); + if (endpoint == NULL) { + // look for endpoint matching local address & port: + endpoint = _FindActiveEndpoint(localAddress, NULL); + if (endpoint == NULL) { + // look for endpoint matching peer address & port and local port: + SocketAddressStorage local(AddressModule()); + local.SetToEmpty(); + local.SetPort(AddressModule()->get_port(localAddress)); + endpoint = _FindActiveEndpoint(*local, peerAddress); + if (endpoint == NULL) { + // last chance: look for endpoint matching local port only: + endpoint = _FindActiveEndpoint(*local, NULL); + } + } + } + if (endpoint == NULL) { TRACE_DOMAIN("_DemuxUnicast(%p) - no matching endpoint found!", buffer); return B_NAME_NOT_FOUND;