+Thu Apr 19 11:40:20 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Added `sender_entry' argument to the function
+ silc_server_packet_relay_to_channel so that we can check
+ whether some destination actually belongs to the same route
+ the sender belongs (ie, we must not resend the packet to the
+ sender). Affected file silcd/packet_send.[ch].
+
+ * Added `servername' field to the SilcClientEntry in the server
+ to hold the name of the server where client is from. Affected
+ file is silcd/idlist.h.
+
Wed Apr 18 22:19:03 EEST 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Moved the channel message encrypting in the router betwen
does not want to register them one by one (if for example SILC client
is run without config files at all).
+ o The ID List must be optimized. When the lists grow the searching
+ becomes a lot slower and is some cases the lists are searched many
+ times, like with channel messages (twice at least). Some sort of
+ hash tables should replace the lists. Thus, the ID cache should be
+ rewritten to use hash tables internally.
+
o Compression routines are missing. The protocol supports packet
compression thus it must be implemented. SILC Comp API must be
defined. zlib package is already included into the lib dir (in CVS,
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
strncat(uh, entry->username, strlen(entry->username));
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
strncat(uh, entry->username, strlen(entry->username));
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
if (!entry->username) {
{
SilcServer server = cmd->server;
unsigned char *tmp, *id_data;
- char *nickname, *username, *realname;
+ char *nickname, *username, *realname, *servername = NULL;
SilcClientID *client_id;
SilcClientEntry client;
SilcIDCacheEntry cache = NULL;
if (strchr(nickname, '@')) {
int len = strcspn(nickname, "@");
nick = silc_calloc(len + 1, sizeof(char));
+ servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
memcpy(nick, nickname, len);
+ memcpy(servername, nickname + len + 1, strlen(nickname) - len);
} else {
nick = strdup(nickname);
}
client->data.registered = TRUE;
client->mode = mode;
+ client->servername = servername;
} else {
/* We have the client already, update the data */
if (strchr(nickname, '@')) {
int len = strcspn(nickname, "@");
nick = silc_calloc(len + 1, sizeof(char));
+ servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
memcpy(nick, nickname, len);
+ memcpy(servername, nickname + len + 1, strlen(nickname) - len);
} else {
nick = strdup(nickname);
}
client->username = strdup(username);
client->userinfo = strdup(realname);
client->mode = mode;
+ client->servername = servername;
if (cache) {
cache->data = nick;
SilcServer server = cmd->server;
uint32 len, id_len;
unsigned char *id_data;
- char *nickname, *username, *realname;
+ char *nickname, *username, *realname, *servername = NULL;
SilcClientID *client_id;
SilcClientEntry client;
SilcIDCacheEntry cache = NULL;
if (strchr(nickname, '@')) {
int len = strcspn(nickname, "@");
nick = silc_calloc(len + 1, sizeof(char));
+ servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
memcpy(nick, nickname, len);
+ memcpy(servername, nickname + len + 1, strlen(nickname) - len);
} else {
nick = strdup(nickname);
}
client = silc_idlist_find_client_by_id(server->global_list,
client_id, &cache);
cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ client->servername = servername;
} else {
/* We have the client already, update the data */
if (strchr(nickname, '@')) {
int len = strcspn(nickname, "@");
nick = silc_calloc(len + 1, sizeof(char));
+ servername = silc_calloc((strlen(nickname) - len) + 1, sizeof(char));
memcpy(nick, nickname, len);
+ memcpy(servername, nickname + len + 1, strlen(nickname) - len);
} else {
nick = strdup(nickname);
}
client->nickname = nick;
client->username = strdup(username);
+ client->servername = servername;
if (cache) {
cache->data = nick;
Generic data structure to hold data common to all ID entries.
+ unsigned char *nickname
+
+ The nickname of the client.
+
+ char *servername
+
+ The name of the server where the client is from. MAy be NULL.
+
char username
Client's usename. This is defined in the following manner:
SilcIDListDataStruct data;
unsigned char *nickname;
+ char *servername;
char *username;
char *userinfo;
SilcClientID *id;
SilcChannelClientEntry chl;
SilcChannelID *id = NULL;
void *sender = NULL;
+ void *sender_entry = NULL;
SILC_LOG_DEBUG(("Processing channel message"));
packet->src_id_type);
if (!sender)
goto out;
- if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
- packet->src_id_type == SILC_ID_CLIENT) {
+ if (packet->src_id_type == SILC_ID_CLIENT) {
silc_list_start(channel->user_list);
while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
+ if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender)) {
+ sender_entry = chl->client;
break;
+ }
}
if (chl == SILC_LIST_END) {
SILC_LOG_DEBUG(("Client not on channel"));
}
}
-
/* Distribute the packet to our local clients. This will send the
packet for further routing as well, if needed. */
silc_server_packet_relay_to_channel(server, sock, channel, sender,
- packet->src_id_type,
+ packet->src_id_type, sender_entry,
packet->buffer->data,
packet->buffer->len, FALSE);
else
id_list = server->global_list;
- router_sock = sock;
- router = sock->user_data;
+ /* If the packet is coming from router then use the sender as the
+ origin of the the packet. If it came from router then check the real
+ sender of the packet and use that as he origin. */
+ if (sock->type == SILC_SOCKET_TYPE_SERVER) {
+ router_sock = sock;
+ router = sock->user_data;
+ } else {
+ void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
+ packet->src_id_type);
+ router = silc_idlist_find_server_by_id(server->global_list,
+ sender_id, NULL);
+ if (!router)
+ router = silc_idlist_find_server_by_id(server->local_list,
+ sender_id, NULL);
+ assert(router != NULL);
+ router_sock = sock;
+ silc_free(sender_id);
+ }
switch(id_type) {
case SILC_ID_CLIENT:
memcpy(tmp, data, data_len);
/* Decrypt the channel message (we don't check the MAC) */
+ /* XXX this could be optimized and removed all together by
+ taking a copy of the original data before encrypting it
+ and thus would not required decrypting. */
if (channel->channel_key &&
!silc_channel_message_payload_decrypt(tmp, data_len,
channel->channel_key,
SilcChannelEntry channel,
void *sender,
SilcIdType sender_type,
+ void *sender_entry,
unsigned char *data,
uint32 data_len,
int force_send);