Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
packet->type != SILC_PACKET_DISCONNECT)
return FALSE;
- /* NEW_CLIENT, NEW_SERVER and RESUME_CLIENT are accepted only without
- source ID and for unregistered connection. */
+ /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and
+ for unregistered connection. */
if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
- packet->type == SILC_PACKET_NEW_SERVER ||
- packet->type == SILC_PACKET_RESUME_CLIENT) &&
+ packet->type == SILC_PACKET_NEW_SERVER) &&
(idata->status & SILC_IDLIST_STATUS_REGISTERED))
return FALSE;
if (server->router_conn && server->router_conn->sock == stream &&
!server->router && server->standalone) {
silc_server_create_connections(server);
+ silc_server_free_sock_user_data(server, stream, NULL);
} else {
/* If backup disconnected then mark that resuming will not be allowed */
if (server->server_type == SILC_ROUTER && !server->backup_router &&
SILC_CONNTYPE_STRING(idata->conn_type),
silc_packet_error_string(error)));
+ if (!silc_packet_stream_is_valid(stream))
+ return;
+
silc_schedule_task_add_timeout(server->schedule,
silc_server_packet_error_timeout,
stream, 0, 0);
SilcID remote_id;
const char *ip;
- SILC_LOG_DEBUG(("Connection authentication completed"));
+ SILC_LOG_DEBUG(("Connection %p authentication completed", sconn));
- sconn->op = NULL;
+ entry->op = NULL;
if (success == FALSE) {
/* Authentication failed */
SILC_STATUS_ERR_AUTH_FAILED, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
return;
}
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
silc_free(entry);
return;
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
silc_free(entry);
return;
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
silc_free(entry);
return;
SILC_STATUS_ERR_AUTH_FAILED, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
silc_free(entry);
return;
SilcHmac hmac_send, hmac_receive;
SilcHash hash;
- sconn->op = NULL;
+ SILC_LOG_DEBUG(("Connection %p, SKE completed", sconn));
+
+ entry->op = NULL;
if (status != SILC_SKE_STATUS_OK) {
/* SKE failed */
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
return;
}
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
return;
}
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
if (sconn->callback)
(*sconn->callback)(server, NULL, sconn->callback_context);
+ silc_server_free_sock_user_data(server, sconn->sock, NULL);
silc_server_connection_free(sconn);
return;
}
entry->data.rekey = rekey;
/* Start connection authentication */
- sconn->op =
+ entry->op =
silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ?
SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth,
auth_data, auth_data_len,
params.flags |= SILC_SKE_SP_FLAG_PFS;
/* Start SILC Key Exchange protocol */
- SILC_LOG_DEBUG(("Starting key exchange protocol"));
+ SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn));
ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
server->public_key, server->private_key, sconn);
if (!ske) {
/* Start key exchange protocol */
params.version = silc_version_string;
params.timeout_secs = server->config->key_exchange_timeout;
- sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
+ entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL);
}
/* Timeout callback that will be called to retry connecting to remote
switch (status) {
case SILC_NET_OK:
- SILC_LOG_DEBUG(("Connection to %s:%d established",
+ SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn,
sconn->remote_host, sconn->remote_port));
/* Continue with key exchange protocol */
server->stat.auth_failures++;
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
goto out;
}
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to backup "
"router established, try later");
+ silc_server_free_sock_user_data(server, sock, NULL);
server->stat.auth_failures++;
/* From here on, wait 20 seconds for the backup router to appear. */
server->stat.auth_failures++;
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_AUTH_FAILED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
goto out;
}
entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to primary "
"router established, try later");
+ silc_server_free_sock_user_data(server, sock, NULL);
server->stat.auth_failures++;
goto out;
}
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to backup "
"router established, try later");
+ silc_server_free_sock_user_data(server, sock, NULL);
server->stat.auth_failures++;
/* From here on, wait 20 seconds for the backup router to appear. */
SILC_LOG_ERROR(("Could not add new server to cache"));
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_AUTH_FAILED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
server->stat.auth_failures++;
goto out;
}
silc_ske_free(ske);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
return;
}
silc_ske_free(ske);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
return;
}
silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
silc_ske_free(ske);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
return;
}
silc_server_disconnect_remote(server, packet_stream,
SILC_STATUS_ERR_BANNED_FROM_SERVER,
deny->reason);
+ silc_server_free_sock_user_data(server, packet_stream, NULL);
return;
}
server->stat.conn_failures++;
silc_server_disconnect_remote(server, packet_stream,
SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
+ silc_server_free_sock_user_data(server, packet_stream, NULL);
return;
}
server->stat.conn_failures++;
silc_server_disconnect_remote(server, packet_stream,
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
+ silc_server_free_sock_user_data(server, packet_stream, NULL);
return;
}
entry->hostname = hostname;
server->stat.conn_failures++;
silc_server_disconnect_remote(server, packet_stream,
SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
+ silc_server_free_sock_user_data(server, packet_stream, NULL);
return;
}
silc_ske_set_callbacks(ske, silc_server_verify_key,
SILC_TASK_CALLBACK(silc_server_close_connection_final)
{
- silc_packet_stream_destroy(context);
+ silc_packet_stream_unref(context);
}
/* Closes connection to socket connection */
const char *hostname;
SilcUInt16 port;
+ if (!silc_packet_stream_is_valid(sock))
+ return;
+
memset(tmp, 0, sizeof(tmp));
// silc_socket_get_error(sock, tmp, sizeof(tmp));
silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
idata->sconn = NULL;
}
+ /* Take a reference and then destroy the stream. The last reference
+ is released later in a timeout callback. */
+ silc_packet_stream_ref(sock);
+ silc_packet_stream_destroy(sock);
+
/* Close connection with timeout */
server->stat.conn_num--;
silc_schedule_task_del_by_all(server->schedule, 0,
if (!idata)
return;
- silc_schedule_task_del_by_context(server->schedule, sock);
+ // silc_schedule_task_del_by_context(server->schedule, sock);
/* Cancel active protocols */
if (idata) {
{
SilcBuffer list, idp, idp2, tmp2;
SilcUInt32 type;
+ void *ptype;
SilcHashTableList htl;
const unsigned char a[1] = { 0x03 };
type = silc_hash_table_count(channel->invite_list);
SILC_PUT16_MSB(type, list->data);
silc_hash_table_list(channel->invite_list, &htl);
- while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
- list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
- type);
+ while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
+ list = silc_argument_payload_encode_one(list, tmp2->data,
+ silc_buffer_len(tmp2),
+ SILC_PTR_TO_32(ptype));
silc_hash_table_list_reset(&htl);
idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
type = silc_hash_table_count(channel->ban_list);
SILC_PUT16_MSB(type, list->data);
silc_hash_table_list(channel->ban_list, &htl);
- while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
- list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
- type);
+ while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2))
+ list = silc_argument_payload_encode_one(list, tmp2->data,
+ silc_buffer_len(tmp2),
+ SILC_PTR_TO_32(ptype));
silc_hash_table_list_reset(&htl);
*ban =