* 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
This commit is contained in:
Axel Dörfler
2006-12-19 03:01:18 +00:00
parent 5aee6a9ee1
commit 79608a2de7
4 changed files with 87 additions and 48 deletions
+1 -10
View File
@@ -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 {
+2 -1
View File
@@ -11,7 +11,8 @@ if $(TARGET_PLATFORM) != haiku {
}
UsePrivateHeaders kernel net ;
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
UsePrivateHeaders net ;
KernelAddon stack :
datalink.cpp
+62 -27
View File
@@ -14,6 +14,7 @@
#include <net_stat.h>
#include <KernelExport.h>
#include <team.h>
#include <util/AutoLock.h>
#include <util/list.h>
#include <fs/select_sync_pool.h>
@@ -24,6 +25,19 @@
#include <sys/time.h>
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:
+22 -10
View File
@@ -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;