From 79608a2de794aaba387e90c9daeed3bdced0dfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 19 Dec 2006 03:01:18 +0000 Subject: [PATCH] * Moved some private members of net_socket into the new net_socket_private structure. * Added an "owner" field that stores the team which created the socket (for netstat only); we would need a different storage for SIGURG if we ever want to support that. * Improved netstat address output: now prints "*" instead of INADDR_ANY. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19562 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/net_socket.h | 11 +-- src/add-ons/kernel/network/stack/Jamfile | 3 +- .../kernel/network/stack/net_socket.cpp | 89 +++++++++++++------ src/bin/network/netstat/netstat.cpp | 32 ++++--- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/headers/private/net/net_socket.h b/headers/private/net/net_socket.h index 66920c384b..0eca484cd1 100644 --- a/headers/private/net/net_socket.h +++ b/headers/private/net/net_socket.h @@ -35,17 +35,8 @@ typedef struct net_socket { bigtime_t timeout; } send, receive; - // TODO: could be moved into a private structure - struct net_socket *parent; - struct list_link link; - uint32 max_backlog; - uint32 child_count; - struct list pending_children; - struct list connected_children; - status_t error; - struct select_sync_pool *select_pool; - benaphore lock; + struct net_socket *parent; } net_socket; struct net_socket_module_info { diff --git a/src/add-ons/kernel/network/stack/Jamfile b/src/add-ons/kernel/network/stack/Jamfile index 4bc5a2b769..7b2bac5e35 100644 --- a/src/add-ons/kernel/network/stack/Jamfile +++ b/src/add-ons/kernel/network/stack/Jamfile @@ -11,7 +11,8 @@ if $(TARGET_PLATFORM) != haiku { } -UsePrivateHeaders kernel net ; +UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; +UsePrivateHeaders net ; KernelAddon stack : datalink.cpp diff --git a/src/add-ons/kernel/network/stack/net_socket.cpp b/src/add-ons/kernel/network/stack/net_socket.cpp index 0b206612c3..051cd71d61 100644 --- a/src/add-ons/kernel/network/stack/net_socket.cpp +++ b/src/add-ons/kernel/network/stack/net_socket.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,19 @@ #include +struct net_socket_private : net_socket { + struct list_link link; + team_id owner; + uint32 max_backlog; + uint32 child_count; + struct list pending_children; + struct list connected_children; + + struct select_sync_pool *select_pool; + benaphore lock; +}; + + void socket_delete(net_socket *socket); int socket_bind(net_socket *socket, const struct sockaddr *address, socklen_t addressLength); @@ -32,13 +46,13 @@ benaphore sSocketLock; static status_t -create_socket(int family, int type, int protocol, net_socket **_socket) +create_socket(int family, int type, int protocol, net_socket_private **_socket) { - struct net_socket *socket = new (std::nothrow) net_socket; + struct net_socket_private *socket = new (std::nothrow) net_socket_private; if (socket == NULL) return B_NO_MEMORY; - memset(socket, 0, sizeof(net_socket)); + memset(socket, 0, sizeof(net_socket_private)); socket->family = family; socket->type = type; socket->protocol = protocol; @@ -55,8 +69,8 @@ create_socket(int family, int type, int protocol, net_socket **_socket) socket->receive.low_water_mark = 1; socket->receive.timeout = B_INFINITE_TIMEOUT; - list_init_etc(&socket->pending_children, offsetof(net_socket, link)); - list_init_etc(&socket->connected_children, offsetof(net_socket, link)); + list_init_etc(&socket->pending_children, offsetof(net_socket_private, link)); + list_init_etc(&socket->connected_children, offsetof(net_socket_private, link)); status = get_domain_protocols(socket); if (status < B_OK) @@ -79,7 +93,7 @@ err1: status_t socket_open(int family, int type, int protocol, net_socket **_socket) { - net_socket *socket; + net_socket_private *socket; status_t status = create_socket(family, type, protocol, &socket); if (status < B_OK) return status; @@ -90,6 +104,8 @@ socket_open(int family, int type, int protocol, net_socket **_socket) return status; } + socket->owner = team_get_current_team_id(); + benaphore_lock(&sSocketLock); list_add_item(&sSocketList, socket); benaphore_unlock(&sSocketLock); @@ -100,8 +116,10 @@ socket_open(int family, int type, int protocol, net_socket **_socket) status_t -socket_close(net_socket *socket) +socket_close(net_socket *_socket) { + net_socket_private *socket = (net_socket_private *)_socket; + if (socket->select_pool) { // notify all pending selects notify_select_event_pool(socket->select_pool, ~0); @@ -222,10 +240,11 @@ socket_get_next_stat(uint32 *_cookie, int family, struct net_stat *stat) { BenaphoreLocker locker(sSocketLock); - net_socket *socket = NULL; + net_socket_private *socket = NULL; uint32 cookie = *_cookie; uint32 count = 0; - while ((socket = (net_socket *)list_get_next_item(&sSocketList, socket)) != NULL) { + while ((socket = (net_socket_private *)list_get_next_item(&sSocketList, socket)) != NULL) { + // TODO: also traverse the pending connections if (count == cookie) break; @@ -241,8 +260,7 @@ socket_get_next_stat(uint32 *_cookie, int family, struct net_stat *stat) stat->family = socket->family; stat->type = socket->type; stat->protocol = socket->protocol; - stat->owner = -1; - + stat->owner = socket->owner; stat->state[0] = '\0'; memcpy(&stat->address, &socket->address, sizeof(struct sockaddr_storage)); memcpy(&stat->peer, &socket->peer, sizeof(struct sockaddr_storage)); @@ -260,8 +278,10 @@ socket_get_next_stat(uint32 *_cookie, int family, struct net_stat *stat) status_t -socket_spawn_pending(net_socket *parent, net_socket **_socket) +socket_spawn_pending(net_socket *_parent, net_socket **_socket) { + net_socket_private *parent = (net_socket_private *)_parent; + BenaphoreLocker locker(parent->lock); // We actually accept more pending connections to compensate for those @@ -270,8 +290,9 @@ socket_spawn_pending(net_socket *parent, net_socket **_socket) if (parent->child_count > 3 * parent->max_backlog / 2) return ENOBUFS; - net_socket *socket; - status_t status = create_socket(parent->family, parent->type, parent->protocol, &socket); + net_socket_private *socket; + status_t status = create_socket(parent->family, parent->type, parent->protocol, + &socket); if (status < B_OK) return status; @@ -280,6 +301,7 @@ socket_spawn_pending(net_socket *parent, net_socket **_socket) socket->receive = parent->receive; socket->options = parent->options & ~SO_ACCEPTCONN; socket->linger = parent->linger; + socket->owner = parent->owner; memcpy(&socket->address, &parent->address, parent->address.ss_len); memcpy(&socket->peer, &parent->peer, parent->peer.ss_len); @@ -294,8 +316,10 @@ socket_spawn_pending(net_socket *parent, net_socket **_socket) void -socket_delete(net_socket *socket) +socket_delete(net_socket *_socket) { + net_socket_private *socket = (net_socket_private *)_socket; + if (socket->parent != NULL) panic("socket still has a parent!"); @@ -311,11 +335,14 @@ socket_delete(net_socket *socket) status_t -socket_dequeue_connected(net_socket *parent, net_socket **_socket) +socket_dequeue_connected(net_socket *_parent, net_socket **_socket) { + net_socket_private *parent = (net_socket_private *)_parent; + benaphore_lock(&parent->lock); - net_socket *socket = (net_socket *)list_remove_head_item(&parent->connected_children); + net_socket_private *socket = (net_socket_private *)list_remove_head_item( + &parent->connected_children); if (socket != NULL) { socket->parent = NULL; parent->child_count--; @@ -336,8 +363,10 @@ socket_dequeue_connected(net_socket *parent, net_socket **_socket) status_t -socket_set_max_backlog(net_socket *socket, uint32 backlog) +socket_set_max_backlog(net_socket *_socket, uint32 backlog) { + net_socket_private *socket = (net_socket_private *)_socket; + // we enforce an upper limit of connections waiting to be accepted if (backlog > 256) backlog = 256; @@ -345,14 +374,14 @@ socket_set_max_backlog(net_socket *socket, uint32 backlog) benaphore_lock(&socket->lock); // first remove the pending connections, then the already connected ones as needed - net_socket *child; + net_socket_private *child; while (socket->child_count > backlog - && (child = (net_socket *)list_remove_tail_item(&socket->pending_children)) != NULL) { + && (child = (net_socket_private *)list_remove_tail_item(&socket->pending_children)) != NULL) { child->parent = NULL; socket->child_count--; } while (socket->child_count > backlog - && (child = (net_socket *)list_remove_tail_item(&socket->connected_children)) != NULL) { + && (child = (net_socket_private *)list_remove_tail_item(&socket->connected_children)) != NULL) { child->parent = NULL; socket_delete(child); socket->child_count--; @@ -371,7 +400,7 @@ socket_set_max_backlog(net_socket *socket, uint32 backlog) status_t socket_connected(net_socket *socket) { - net_socket *parent = socket->parent; + net_socket_private *parent = (net_socket_private *)socket->parent; if (parent == NULL) return B_BAD_VALUE; @@ -389,9 +418,11 @@ socket_connected(net_socket *socket) status_t -socket_request_notification(net_socket *socket, uint8 event, uint32 ref, +socket_request_notification(net_socket *_socket, uint8 event, uint32 ref, selectsync *sync) { + net_socket_private *socket = (net_socket_private *)_socket; + benaphore_lock(&socket->lock); status_t status = add_select_sync_pool_entry(&socket->select_pool, sync, @@ -430,8 +461,10 @@ socket_request_notification(net_socket *socket, uint8 event, uint32 ref, status_t -socket_cancel_notification(net_socket *socket, uint8 event, selectsync *sync) +socket_cancel_notification(net_socket *_socket, uint8 event, selectsync *sync) { + net_socket_private *socket = (net_socket_private *)_socket; + benaphore_lock(&socket->lock); status_t status = remove_select_sync_pool_entry(&socket->select_pool, @@ -443,8 +476,9 @@ socket_cancel_notification(net_socket *socket, uint8 event, selectsync *sync) status_t -socket_notify(net_socket *socket, uint8 event, int32 value) +socket_notify(net_socket *_socket, uint8 event, int32 value) { + net_socket_private *socket = (net_socket_private *)_socket; bool notify = true; switch (event) { @@ -492,7 +526,8 @@ socket_accept(net_socket *socket, struct sockaddr *address, socklen_t *_addressL return status; if (address && *_addressLength > 0) { - memcpy(address, &accepted->peer, min_c(*_addressLength, accepted->peer.ss_len)); + memcpy(address, &accepted->peer, min_c(*_addressLength, + min_c(accepted->peer.ss_len, sizeof(sockaddr_storage)))); *_addressLength = accepted->peer.ss_len; } @@ -983,7 +1018,7 @@ socket_std_ops(int32 op, ...) // initialize the main stack if not done so already //module_info *module; //return get_module(NET_STARTER_MODULE_NAME, &module); - list_init_etc(&sSocketList, offsetof(net_socket, link)); + list_init_etc(&sSocketList, offsetof(net_socket_private, link)); return benaphore_init(&sSocketLock, "socket list"); } case B_MODULE_UNINIT: diff --git a/src/bin/network/netstat/netstat.cpp b/src/bin/network/netstat/netstat.cpp index 2945fb96f1..526e0f3e52 100644 --- a/src/bin/network/netstat/netstat.cpp +++ b/src/bin/network/netstat/netstat.cpp @@ -55,23 +55,35 @@ inet_print_address(sockaddr* _address) sockaddr_in& address = *(sockaddr_in *)_address; if (address.sin_family != AF_INET || address.sin_len == 0) { - printf("%-28s", "-"); + printf("%-30s", "-"); return; } hostent* host = gethostbyaddr((const char*)_address, sizeof(sockaddr_in), AF_INET); servent* service = getservbyport(ntohs(address.sin_port), NULL); - char buffer[128]; - int length = strlcpy(buffer, host != NULL - ? host->h_name : inet_ntoa(address.sin_addr), sizeof(buffer)); - - if (service != NULL) - snprintf(buffer + length, sizeof(buffer) - length, ":%s", service->s_name); + const char *hostName; + if (host != NULL) + hostName = host->h_name; + else if (address.sin_addr.s_addr == INADDR_ANY) + hostName = "*"; else - snprintf(buffer + length, sizeof(buffer) - length, ":%u", ntohs(address.sin_port)); + hostName = inet_ntoa(address.sin_addr); - printf("%-28s", buffer); + char buffer[128]; + int length = strlcpy(buffer, hostName, sizeof(buffer)); + + char port[64]; + if (service != NULL) + strlcpy(port, service->s_name, sizeof(port)); + else if (address.sin_port == 0) + strcpy(port, "*"); + else + snprintf(port, sizeof(port), "%u", ntohs(address.sin_port)); + + snprintf(buffer + length, sizeof(buffer) - length, ":%s", port); + + printf("%-30s", buffer); } @@ -141,7 +153,7 @@ main(int argc, char** argv) bool printProgram = true; // TODO: add some program options... :-) - printf("Proto Local Address Foreign Address State Program\n"); + printf("Proto Local Address Foreign Address State Program\n"); uint32 cookie = 0; int family = -1;