/* Initialize ID caches */
server->local_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->local_list->servers = silc_idcache_alloc(0, NULL);
- server->local_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* These are allocated for normal server as well as these hold some
global information that the server has fetched from its router. For
router these are used as they are supposed to be used on router. */
server->global_list->clients =
- silc_idcache_alloc(0, silc_idlist_client_destructor);
- server->global_list->servers = silc_idcache_alloc(0, NULL);
- server->global_list->channels = silc_idcache_alloc(0, NULL);
+ silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
+ server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
+ server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
/* Allocate the entire socket list that is used in server. Eventually
all connections will have entry in this table (it is a table of
server->id = id;
server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
- server->id_string_len = silc_id_get_len(SILC_ID_SERVER);
+ server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
server->id_type = SILC_ID_SERVER;
server->server_name = server->config->server_info->server_name;
SilcBuffer packet;
SilcServerHBContext hb_context;
unsigned char *id_string;
+ uint32 id_len;
SilcIDListData idata;
SILC_LOG_DEBUG(("Start"));
/* Send NEW_SERVER packet to the router. We will become registered
to the SILC network after sending this packet. */
id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
- packet = silc_buffer_alloc(2 + 2 + SILC_ID_SERVER_LEN +
- strlen(server->server_name));
+ id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
+ packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
silc_buffer_format(packet,
- SILC_STR_UI_SHORT(SILC_ID_SERVER_LEN),
- SILC_STR_UI_XNSTRING(id_string, SILC_ID_SERVER_LEN),
+ SILC_STR_UI_SHORT(id_len),
+ SILC_STR_UI_XNSTRING(id_string, id_len),
SILC_STR_UI_SHORT(strlen(server->server_name)),
SILC_STR_UI_XNSTRING(server->server_name,
strlen(server->server_name)),
SilcServerKEInternalContext *proto_ctx;
int sock, port;
void *cconfig, *sconfig, *rconfig;
+ SilcServerConfigSectionDenyConnection *deny;
SILC_LOG_DEBUG(("Accepting new connection"));
later when outgoing data is available. */
SILC_REGISTER_CONNECTION_FOR_IO(sock);
+ port = server->sockets[fd]->port; /* Listenning port */
+
+ /* Check whether this connection is denied to connect to us. */
+ deny = silc_server_config_denied_conn(server->config, newsocket->ip, port);
+ if (!deny)
+ deny = silc_server_config_denied_conn(server->config, newsocket->hostname,
+ port);
+ if (deny) {
+ /* The connection is denied */
+ silc_server_disconnect_remote(server, newsocket, deny->comment ?
+ deny->comment :
+ "Server closed connection: "
+ "Connection refused");
+ server->stat.conn_failures++;
+ return;
+ }
+
/* Check whether we have configred this sort of connection at all. We
have to check all configurations since we don't know what type of
connection this is. */
- port = server->sockets[fd]->port; /* Listenning port */
if (!(cconfig = silc_server_config_find_client_conn(server->config,
newsocket->ip, port)))
cconfig = silc_server_config_find_client_conn(server->config,
and other information is created after we have received NEW_CLIENT
packet from client. */
client = silc_idlist_add_client(server->local_list,
- NULL, 0, NULL, NULL, NULL, NULL, sock);
+ NULL, NULL, NULL, NULL, NULL, sock);
if (!client) {
SILC_LOG_ERROR(("Could not add new client to cache"));
silc_free(sock->user_data);
if (client && client->id) {
void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
- if (!id || SILC_ID_CLIENT_COMPARE(client->id, id)) {
+ if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
silc_free(id);
goto out;
}
if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
packet->dst_id_type == SILC_ID_SERVER &&
sock->type != SILC_SOCKET_TYPE_CLIENT &&
- SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
+ memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
/* Route the packet to fastest route for the destination ID */
void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
if (notify && !server->standalone && server->router)
silc_server_send_notify_signoff(server, server->router->connection,
server->server_type == SILC_SERVER ?
- FALSE : TRUE, client->id,
- SILC_ID_CLIENT_LEN, signoff);
+ FALSE : TRUE, client->id, signoff);
/* Remove client from all channels */
if (notify)
silc_buffer_free(idp);
}
- if (silc_idcache_find_by_id(server->local_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->local_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
silc_idcache_list_free(list);
}
- if (silc_idcache_find_by_id(server->global_list->clients,
- SILC_ID_CACHE_ANY, SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(server->global_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
to our primary route. */
if (broadcast && server->standalone == FALSE)
silc_server_send_new_channel(server, server->router->connection, TRUE,
- channel_name, entry->id, SILC_ID_CHANNEL_LEN,
+ channel_name, entry->id,
+ silc_id_get_len(entry->id, SILC_ID_CHANNEL),
entry->mode);
server->stat.my_channels++;
to our primary route. */
if (broadcast && server->standalone == FALSE)
silc_server_send_new_channel(server, server->router->connection, TRUE,
- channel_name, entry->id, SILC_ID_CHANNEL_LEN,
+ channel_name, entry->id,
+ silc_id_get_len(entry->id, SILC_ID_CHANNEL),
entry->mode);
server->stat.my_channels++;
SilcBuffer idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->clients, SILC_ID_CACHE_ANY,
- SILC_ID_SERVER, &list)) {
+ if (silc_idcache_get_all(id_list->servers, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
entry = (SilcServerEntry)id_cache->context;
SilcBuffer idp;
/* Go through all clients in the list */
- if (silc_idcache_find_by_id(id_list->clients, SILC_ID_CACHE_ANY,
- SILC_ID_CLIENT, &list)) {
+ if (silc_idcache_get_all(id_list->clients, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
}
static SilcBuffer
-silc_server_announce_encode_join(uint32 argc, ...)
+silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
{
va_list ap;
va_start(ap, argc);
- return silc_notify_payload_encode(SILC_NOTIFY_TYPE_JOIN, argc, ap);
+ return silc_notify_payload_encode(notify, argc, ap);
}
/* Returns assembled packets for channel users of the `channel'. */
void silc_server_announce_get_channel_users(SilcServer server,
SilcChannelEntry channel,
- SilcBuffer *channel_users)
+ SilcBuffer *channel_users,
+ SilcBuffer *channel_users_modes)
{
SilcChannelClientEntry chl;
SilcBuffer chidp, clidp;
SilcBuffer tmp;
int len;
+ unsigned char mode[4];
SILC_LOG_DEBUG(("Start"));
silc_list_start(channel->user_list);
while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
- tmp = silc_server_announce_encode_join(2, clidp->data, clidp->len,
- chidp->data, chidp->len);
+
+ /* JOIN Notify */
+ tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
+ clidp->data, clidp->len,
+ chidp->data, chidp->len);
len = tmp->len;
*channel_users =
silc_buffer_realloc(*channel_users,
silc_buffer_put(*channel_users, tmp->data, tmp->len);
silc_buffer_pull(*channel_users, len);
- silc_buffer_free(clidp);
silc_buffer_free(tmp);
+
+ /* CUMODE notify for mode change on the channel */
+ SILC_PUT32_MSB(chl->mode, mode);
+ tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
+ 3, clidp->data, clidp->len,
+ mode, 4,
+ clidp->data, clidp->len);
+ len = tmp->len;
+ *channel_users_modes =
+ silc_buffer_realloc(*channel_users_modes,
+ (*channel_users_modes ?
+ (*channel_users_modes)->truelen + len : len));
+ silc_buffer_pull_tail(*channel_users_modes,
+ ((*channel_users_modes)->end -
+ (*channel_users_modes)->data));
+
+ silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
+ silc_buffer_pull(*channel_users_modes, len);
+ silc_buffer_free(tmp);
+
+ silc_buffer_free(clidp);
}
silc_buffer_free(chidp);
}
void silc_server_announce_get_channels(SilcServer server,
SilcIDList id_list,
SilcBuffer *channels,
- SilcBuffer *channel_users)
+ SilcBuffer *channel_users,
+ SilcBuffer *channel_users_modes)
{
SilcIDCacheList list;
SilcIDCacheEntry id_cache;
SilcChannelEntry channel;
unsigned char *cid;
+ uint32 id_len;
uint16 name_len;
int len;
SILC_LOG_DEBUG(("Start"));
/* Go through all channels in the list */
- if (silc_idcache_find_by_id(id_list->channels, SILC_ID_CACHE_ANY,
- SILC_ID_CHANNEL, &list)) {
+ if (silc_idcache_get_all(id_list->channels, &list)) {
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
channel = (SilcChannelEntry)id_cache->context;
cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
name_len = strlen(channel->channel_name);
- len = 4 + name_len + SILC_ID_CHANNEL_LEN + 4;
+ len = 4 + name_len + id_len + 4;
*channels =
silc_buffer_realloc(*channels,
(*channels ? (*channels)->truelen + len : len));
SILC_STR_UI_SHORT(name_len),
SILC_STR_UI_XNSTRING(channel->channel_name,
name_len),
- SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
- SILC_STR_UI_XNSTRING(cid, SILC_ID_CHANNEL_LEN),
+ SILC_STR_UI_SHORT(id_len),
+ SILC_STR_UI_XNSTRING(cid, id_len),
SILC_STR_UI_INT(channel->mode),
SILC_STR_END);
silc_buffer_pull(*channels, len);
silc_server_announce_get_channel_users(server, channel,
- channel_users);
+ channel_users,
+ channel_users_modes);
silc_free(cid);
void silc_server_announce_channels(SilcServer server)
{
- SilcBuffer channels = NULL, channel_users = NULL;
+ SilcBuffer channels = NULL, channel_users = NULL, channel_users_modes = NULL;
SILC_LOG_DEBUG(("Announcing channels and channel users"));
/* Get channels and channel users in local list */
silc_server_announce_get_channels(server, server->local_list,
- &channels, &channel_users);
+ &channels, &channel_users,
+ &channel_users_modes);
/* Get channels and channel users in global list */
silc_server_announce_get_channels(server, server->global_list,
- &channels, &channel_users);
+ &channels, &channel_users,
+ &channel_users_modes);
if (channels) {
silc_buffer_push(channels, channels->data - channels->head);
silc_buffer_free(channel_users);
}
+
+ if (channel_users_modes) {
+ silc_buffer_push(channel_users_modes,
+ channel_users_modes->data - channel_users_modes->head);
+ SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes->data,
+ channel_users_modes->len);
+
+ /* Send the packet */
+ silc_server_packet_send(server, server->router->connection,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ channel_users_modes->data,
+ channel_users_modes->len,
+ FALSE);
+
+ silc_buffer_free(channel_users_modes);
+ }
}
/* Failure timeout callback. If this is called then we will immediately
SilcBuffer idp;
uint32 list_count = 0;
+ /* XXX rewrite - this does not support IPv6 based Client ID's. */
+
client_id_list = silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) *
silc_list_count(channel->user_list));
client_mode_list = silc_buffer_alloc(4 *
SILC_GET32_MSB(mode, mode_list->data);
silc_buffer_pull(mode_list, 4);
- if (noadd && !SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
+ if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
silc_free(client_id);
continue;
}
/* We don't have that client anywhere, add it. The client is added
to global list since server didn't have it in the lists so it must be
global. */
- client = silc_idlist_add_client(server->global_list, NULL, 0, NULL,
- NULL,
+ client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
silc_id_dup(client_id, SILC_ID_CLIENT),
sock->user_data, NULL);
if (!client) {
SilcChannelEntry channel;
SilcChannelClientEntry chl;
unsigned char *cid;
+ uint32 id_len;
uint16 name_len;
int len;
continue;
cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
name_len = strlen(channel->channel_name);
- len = 4 + name_len + SILC_ID_CHANNEL_LEN + 4;
+ len = 4 + name_len + id_len + 4;
buffer = silc_buffer_realloc(buffer,
(buffer ? (buffer)->truelen + len : len));
silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
SILC_STR_UI_SHORT(name_len),
SILC_STR_UI_XNSTRING(channel->channel_name,
name_len),
- SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
- SILC_STR_UI_XNSTRING(cid, SILC_ID_CHANNEL_LEN),
+ SILC_STR_UI_SHORT(id_len),
+ SILC_STR_UI_XNSTRING(cid, id_len),
SILC_STR_UI_INT(chl->mode), /* Client's mode */
SILC_STR_END);
silc_buffer_pull(buffer, len);