we will send the packet to that server. */
router = (SilcServerEntry)dst_sock->user_data;
idata = (SilcIDListData)router;
- //assert(client->router == server->id_entry);
silc_server_send_private_message(server, dst_sock,
idata->send_key,
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Welcome to the SILC Network %s@%s",
username, sock->hostname));
+ if (server->server_type == SILC_ROUTER) {
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("There are %d clients on %d servers in SILC "
+ "Network", server->stat.clients,
+ server->stat.servers));
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("There are %d clients on %d server in our cell",
+ server->stat.cell_clients,
+ server->stat.cell_servers));
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("I have %d clients, %d channels, %d servers and "
+ "%d routers",
+ server->stat.my_clients,
+ server->stat.my_channels,
+ server->stat.my_servers,
+ server->stat.my_routers));
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("%d server operators and %d router operators "
+ "online",
+ server->stat.my_server_ops,
+ server->stat.my_router_ops));
+ } else {
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("I have %d clients and %d channels formed",
+ server->stat.my_clients,
+ server->stat.my_channels));
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("%d operators online",
+ server->stat.my_server_ops));
+ }
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your host is %s, running version %s",
server->config->server_info->server_name,
buffer->data, buffer->len, FALSE);
}
-#if 0
- /* If the packet is originated from the one who sent it to us we know
- that the ID belongs to our cell, unless the sender was router. */
- tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
- tmpserver = (SilcServerEntry)sock->user_data;
-
- if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
- sock->type == SILC_SOCKET_TYPE_SERVER) {
- id_list = server->local_list;
- router_sock = sock;
- router = sock->user_data;
- /* router = server->id_entry; */
- } else {
- id_list = server->global_list;
- router_sock = (SilcSocketConnection)server->router->connection;
- router = server->router;
- }
-
- silc_free(tmpid);
-#endif
-
if (sock->type == SILC_SOCKET_TYPE_SERVER)
id_list = server->local_list;
else
router, router_sock);
entry->nickname = NULL;
+ if (sock->type == SILC_SOCKET_TYPE_SERVER)
+ server->stat.cell_clients++;
+ server->stat.clients++;
+
#if 0
/* XXX Adding two ID's with same IP number replaces the old entry thus
gives wrong route. Thus, now disabled until figured out a better way
list. Cell wide information however is kept in the local list. */
silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
+ if (sock->type == SILC_SOCKET_TYPE_SERVER)
+ server->stat.cell_servers++;
+ server->stat.servers++;
+
#if 0
/* Add route cache for this ID */
silc_server_route_add(silc_server_route_hash(
router hence global channel. */
silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id,
server->router->connection, NULL);
+
+ server->stat.channels++;
}
/* Received notify packet. Server can receive notify packets from router.
silc_list_add(channel->user_list, chl);
silc_list_add(client->channels, chl);
+ server->stat.chanclients++;
+
/* Send JOIN notify to local clients on the channel. As we are router
it is assured that this is sent only to our local clients and locally
connected servers if needed. */
/* Remove the client entry */
silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
+ server->stat.clients--;
SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
silc_id_render(id, SILC_ID_CLIENT),
NULL);
if (id_entry) {
silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
+ server->stat.servers--;
SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
silc_id_render(id, SILC_ID_SERVER),
NULL);
if (id_entry) {
silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
+ server->stat.channels--;
SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
silc_id_render(id, SILC_ID_CHANNEL),
SILC_LOG_DEBUG(("Accepting new connection"));
+ server->stat.conn_attempts++;
+
sock = silc_net_accept_connection(server->sock);
if (sock < 0) {
SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
+ server->stat.conn_failures++;
return;
}
/*silc_server_send_notify("Server is full, trying to redirect..."); */
} else {
SILC_LOG_ERROR(("Refusing connection, server is full"));
+ server->stat.conn_failures++;
}
return;
}
if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
!newsocket->ip) {
SILC_LOG_ERROR(("IP/DNS lookup failed"));
+ server->stat.conn_failures++;
return;
}
if (!newsocket->hostname)
protocol but will not start it yet. The connector will be the
initiator of the protocol thus we will wait for initiation from
there before we start the protocol. */
+ server->stat.auth_attempts++;
silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
&newsocket->protocol, proto_ctx,
silc_server_accept_new_connection_second);
sock->protocol = NULL;
silc_server_disconnect_remote(server, sock, "Server closed connection: "
"Key exchange failed");
+ server->stat.auth_failures++;
return;
}
sock->protocol = NULL;
silc_server_disconnect_remote(server, sock, "Server closed connection: "
"Authentication failed");
+ server->stat.auth_failures++;
return;
}
break;
}
+ server->stat.my_clients++;
+
id_entry = (void *)client;
break;
}
break;
}
+ if (sock->type == SILC_SOCKET_TYPE_SERVER)
+ server->stat.my_servers++;
+ else
+ server->stat.my_routers++;
+
id_entry = (void *)new_server;
/* There is connection to other server now, if it is router then
/* Packet sending */
if (type == SILC_TASK_WRITE) {
+ server->stat.packets_sent++;
+
if (sock->outbuf->data - sock->outbuf->head)
silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
return;
}
+ server->stat.packets_received++;
+
/* Get keys and stuff from ID entry */
idata = (SilcIDListData)sock->user_data;
if (idata) {
void silc_server_close_connection(SilcServer server,
SilcSocketConnection sock)
{
-
SILC_LOG_DEBUG(("Closing connection %d", sock->sock));
/* We won't listen for this connection anymore */
/* Free the client entry and everything in it */
silc_idlist_del_data(user_data);
silc_idlist_del_client(server->local_list, user_data);
+ server->stat.my_clients--;
break;
}
case SILC_SOCKET_TYPE_SERVER:
/* Free the server entry */
silc_idlist_del_data(user_data);
silc_idlist_del_server(server->local_list, user_data);
+ server->stat.my_servers--;
break;
}
default:
clidp->data, clidp->len);
silc_idlist_del_channel(server->local_list, channel);
+ server->stat.my_channels--;
continue;
}
/* Remove from list */
silc_list_del(channel->user_list, chl);
silc_free(chl);
+ server->stat.my_chanclients--;
/* Send notify to channel about client leaving SILC and thus
the entire channel. */
silc_idlist_del_channel(server->local_list, channel);
silc_buffer_free(clidp);
+ server->stat.my_channels--;
return FALSE;
}
/* Remove from list */
silc_list_del(channel->user_list, chl);
silc_free(chl);
+ server->stat.my_chanclients--;
/* If there is no global users on the channel anymore mark the channel
as local channel. */
!silc_server_channel_has_local(channel)) {
silc_idlist_del_channel(server->local_list, channel);
silc_buffer_free(clidp);
+ server->stat.my_channels--;
return FALSE;
}
channel_name, entry->id, SILC_ID_CHANNEL_LEN);
}
+ server->stat.my_channels++;
+
return entry;
}
/* Server statistics structure. This holds various statistics about
various things. */
-/* XXX TODO */
typedef struct {
-
+ /* Local stats (server and router) */
+ unsigned long my_clients; /* Locally connected clients */
+ unsigned long my_servers; /* Locally connected servers */
+ unsigned long my_routers; /* Locally connected routers */
+ unsigned long my_channels; /* Locally created channels */
+ unsigned long my_chanclients; /* Local clients on local channels */
+ unsigned long my_aways; /* Local clients away (XXX) */
+ unsigned long my_server_ops; /* Local server operators */
+ unsigned long my_router_ops; /* Local router operators */
+
+ /* Global stats (mainly for router) */
+ unsigned long cell_clients; /* All clients in cell */
+ unsigned long cell_servers; /* All servers in cell */
+ unsigned long cell_channels; /* All channels in cell */
+ unsigned long cell_chanclients; /* All clients on cell's channels */
+ unsigned long clients; /* All clients */
+ unsigned long servers; /* All servers */
+ unsigned long routers; /* All routers */
+ unsigned long channels; /* All channels */
+ unsigned long chanclients; /* All clients on channels */
+ unsigned long server_ops; /* All server operators */
+ unsigned long router_ops; /* All router operators */
+
+ /* General */
+ unsigned long conn_attempts; /* Connection attempts */
+ unsigned long conn_failures; /* Connection failure */
+ unsigned long auth_attempts; /* Authentication attempts */
+ unsigned long auth_failures; /* Authentication failures */
+ unsigned long packets_sent; /* Sent packets */
+ unsigned long packets_received; /* Received packets */
} SilcServerStatistics;
typedef struct {
SilcRng rng;
/* Server statistics */
- SilcServerStatistics stats;
+ SilcServerStatistics stat;
/* Pending command queue */
SilcDList pending_commands;