* 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
This commit is contained in:
@@ -188,7 +188,6 @@ private:
|
|||||||
|
|
||||||
UdpEndpoint *_FindActiveEndpoint(const sockaddr *ourAddress,
|
UdpEndpoint *_FindActiveEndpoint(const sockaddr *ourAddress,
|
||||||
const sockaddr *peerAddress);
|
const sockaddr *peerAddress);
|
||||||
UdpEndpoint* _EndpointFor(net_buffer* buffer);
|
|
||||||
status_t _DemuxBroadcast(net_buffer *buffer);
|
status_t _DemuxBroadcast(net_buffer *buffer);
|
||||||
status_t _DemuxUnicast(net_buffer *buffer);
|
status_t _DemuxUnicast(net_buffer *buffer);
|
||||||
|
|
||||||
@@ -303,12 +302,13 @@ UdpDomainSupport::DeliverError(status_t error, net_buffer* buffer)
|
|||||||
|
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
// RFC 1122 4.1.3.3:
|
// Forward the error to the socket
|
||||||
// TODO: Pass to the application layer all ICMP error messages
|
UdpEndpoint* endpoint = _FindActiveEndpoint(buffer->source,
|
||||||
|
buffer->destination);
|
||||||
UdpEndpoint* endpoint = _EndpointFor(buffer);
|
if (endpoint != NULL) {
|
||||||
if (endpoint != NULL)
|
|
||||||
gSocketModule->notify(endpoint->Socket(), B_SELECT_ERROR, error);
|
gSocketModule->notify(endpoint->Socket(), B_SELECT_ERROR, error);
|
||||||
|
endpoint->NotifyOne();
|
||||||
|
}
|
||||||
|
|
||||||
gBufferModule->free(buffer);
|
gBufferModule->free(buffer);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -500,6 +500,8 @@ UdpEndpoint *
|
|||||||
UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress,
|
UdpDomainSupport::_FindActiveEndpoint(const sockaddr *ourAddress,
|
||||||
const sockaddr *peerAddress)
|
const sockaddr *peerAddress)
|
||||||
{
|
{
|
||||||
|
ASSERT_LOCKED_MUTEX(&fLock);
|
||||||
|
|
||||||
TRACE_DOMAIN("finding Endpoint for %s <- %s",
|
TRACE_DOMAIN("finding Endpoint for %s <- %s",
|
||||||
AddressString(fDomain, ourAddress, true).Data(),
|
AddressString(fDomain, ourAddress, true).Data(),
|
||||||
AddressString(fDomain, peerAddress, 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
|
status_t
|
||||||
UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
|
UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
|
||||||
{
|
{
|
||||||
@@ -587,11 +558,31 @@ UdpDomainSupport::_DemuxBroadcast(net_buffer *buffer)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UdpDomainSupport::_DemuxUnicast(net_buffer *buffer)
|
UdpDomainSupport::_DemuxUnicast(net_buffer* buffer)
|
||||||
{
|
{
|
||||||
TRACE_DOMAIN("_DemuxUnicast(%p)", 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) {
|
if (endpoint == NULL) {
|
||||||
TRACE_DOMAIN("_DemuxUnicast(%p) - no matching endpoint found!", buffer);
|
TRACE_DOMAIN("_DemuxUnicast(%p) - no matching endpoint found!", buffer);
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
|
|||||||
Reference in New Issue
Block a user