diff --git a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp index 45e8f6cacd..082e1494d1 100644 --- a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.cpp @@ -415,3 +415,26 @@ EndpointManager::ReplyWithReset(tcp_segment_header &segment, return status; } + +void +EndpointManager::DumpEndpoints() const +{ + kprintf("-------- TCP Domain %p ---------\n", this); + kprintf("%10s %20s %20s %8s %8s %12s\n", "address", "local", "peer", + "recv-q", "send-q", "state"); + + ConnectionTable::Iterator it = fConnectionHash.GetIterator(); + + while (it.HasNext()) { + TCPEndpoint *endpoint = it.Next(); + + char localBuf[64], peerBuf[64]; + endpoint->LocalAddress().AsString(localBuf, sizeof(localBuf), true); + endpoint->PeerAddress().AsString(peerBuf, sizeof(peerBuf), true); + + kprintf("%p %20s %20s %8lu %8lu %12s\n", endpoint, localBuf, peerBuf, + endpoint->fReceiveQueue.Available(), endpoint->fSendQueue.Used(), + name_for_state(endpoint->State())); + } +} + diff --git a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.h b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.h index 152d8d359a..04c7365c0e 100644 --- a/src/add-ons/kernel/network/protocols/tcp/EndpointManager.h +++ b/src/add-ons/kernel/network/protocols/tcp/EndpointManager.h @@ -77,6 +77,8 @@ class EndpointManager : public DoublyLinkedListLinkImpl { status_t ReplyWithReset(tcp_segment_header &segment, net_buffer *buffer); + void DumpEndpoints() const; + net_domain *Domain() const { return fDomain; } net_address_module_info *AddressModule() const { return Domain()->address_module; } diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index c66ed86a6c..b2b819a59a 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -851,6 +851,42 @@ TCPEndpoint::Spawn(TCPEndpoint *parent, tcp_segment_header &segment, } +void +TCPEndpoint::DumpInternalState() const +{ + kprintf("Lock: { sem: %ld, holder: %ld, recursion: %i }\n", + fLock.sem, fLock.holder, fLock.recursion); + kprintf("AcceptSem: %ld\n", fAcceptSemaphore); + kprintf("Options: 0x%lx\n", (uint32)fOptions); + kprintf("SendWindowShift: %lu\n", (uint32)fSendWindowShift); + kprintf("ReceiveWindowShift: %lu\n", (uint32)fReceiveWindowShift); + kprintf("SendUnacknowledged: %lu\n", (uint32)fSendUnacknowledged); + kprintf("SendNext: %lu\n", (uint32)fSendNext); + kprintf("SendMax: %lu\n", (uint32)fSendMax); + kprintf("SendWindow: %lu\n", fSendWindow); + kprintf("SendMaxWindow: %lu\n", fSendMaxWindow); + kprintf("SendMaxSegmentSize: %lu\n", fSendMaxSegmentSize); + kprintf("Send-Q: %lu / %lu\n", fSendQueue.Used(), fSendQueue.Size()); + kprintf("LastAcknowledgeSent: %lu\n", (uint32)fLastAcknowledgeSent); + kprintf("InitialSendSequence: %lu\n", (uint32)fInitialSendSequence); + kprintf("DuplicateAcknowledgeCount: %lu\n", fDuplicateAcknowledgeCount); + kprintf("ReceiveNext: %lu\n", (uint32)fReceiveNext); + kprintf("ReceiveMaxAdvertised: %lu\n", (uint32)fReceiveMaxAdvertised); + kprintf("ReceiveWindow: %lu\n", (uint32)fReceiveWindow); + kprintf("ReceiveMaxSegmentSize: %lu\n", (uint32)fReceiveMaxSegmentSize); + kprintf("Recv-Q: %lu / %lu\n", fReceiveQueue.Available(), + fReceiveQueue.Size()); + kprintf("InitialReceiveSequence: %lu\n", (uint32)fInitialReceiveSequence); + kprintf("RoundTripTime: %ld (dev %ld)\n", fRoundTripTime, + fRoundTripDeviation); + kprintf("RetransmitTimeout: %llu\n", (uint64)fRetransmitTimeout); + kprintf("CongestionWindow: %lu\n", fCongestionWindow); + kprintf("SlowStartThreshold: %lu\n", fSlowStartThreshold); + kprintf("State: %s\n", name_for_state(fState)); + kprintf("Flags: 0x%lx\n", fFlags); +} + + int32 TCPEndpoint::_SynchronizeSentReceive(tcp_segment_header &segment, net_buffer *buffer) { diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h index e60a372857..a1d16f722b 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h @@ -79,6 +79,8 @@ class TCPEndpoint : public net_protocol, public ProtocolSocket { int32 Spawn(TCPEndpoint *parent, tcp_segment_header& segment, net_buffer *buffer); + void DumpInternalState() const; + private: friend class EndpointManager; diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp index 884908e193..95ba38efab 100644 --- a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp @@ -661,6 +661,33 @@ tcp_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, } +static int +dump_endpoints(int argc, char *argv[]) +{ + EndpointManagerList::Iterator it = sEndpointManagers.GetIterator(); + + while (it.HasNext()) + it.Next()->DumpEndpoints(); + + return 0; +} + + +static int +dump_endpoint(int argc, char *argv[]) +{ + if (argc < 2) { + kprintf("usage: tcp_endpoint [address]\n"); + return 0; + } + + TCPEndpoint *endpoint = (TCPEndpoint *)strtoul(argv[1], NULL, 16); + endpoint->DumpInternalState(); + + return 0; +} + + // #pragma mark - @@ -692,6 +719,11 @@ tcp_init() if (status < B_OK) return status; + add_debugger_command("tcp_endpoints", dump_endpoints, + "lists all open TCP endpoints"); + add_debugger_command("tcp_endpoint", dump_endpoint, + "dumps a TCP endpoint internal state"); + return B_OK; } @@ -699,6 +731,8 @@ tcp_init() static status_t tcp_uninit() { + remove_debugger_command("tcp_endpoint", dump_endpoint); + remove_debugger_command("tcp_endpoints", dump_endpoints); recursive_lock_destroy(&sEndpointManagersLock); return B_OK; }