&newsocket);
server->sockets[sock[i]] = newsocket;
+
+ /* Perform name and address lookups to resolve the listenning address
+ and port. */
+ if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname,
+ &newsocket->ip)) {
+ if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
+ !newsocket->ip) {
+ SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
+ newsocket->hostname ? newsocket->hostname :
+ newsocket->ip ? newsocket->ip : ""));
+ server->stat.conn_failures++;
+ goto err0;
+ }
+ if (!newsocket->hostname)
+ newsocket->hostname = strdup(newsocket->ip);
+ }
+ newsocket->port = silc_net_get_local_port(sock[i]);
/* Put the allocated socket pointer also to the entry allocated above
for fast back-referencing to the socket list. */
SilcServer server = (SilcServer)context;
SilcSocketConnection newsocket;
SilcServerKEInternalContext *proto_ctx;
- int sock;
+ int sock, port;
+ void *config;
SILC_LOG_DEBUG(("Accepting new connection"));
}
newsocket->port = silc_net_get_remote_port(sock);
+ /* Register the connection for network input and output. This sets
+ that scheduler will listen for incoming packets for this connection
+ and sets that outgoing packets may be sent to this connection as well.
+ However, this doesn't set the scheduler for outgoing traffic, it
+ will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
+ later when outgoing data is available. */
+ SILC_REGISTER_CONNECTION_FOR_IO(sock);
+
+ /* 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 (!(config = silc_server_config_find_client_conn(server->config,
+ newsocket->ip, port)))
+ if (!(config = silc_server_config_find_client_conn(server->config,
+ newsocket->hostname,
+ port)))
+ if (!(config = silc_server_config_find_server_conn(server->config,
+ newsocket->ip,
+ port)))
+ if (!(config = silc_server_config_find_server_conn(server->config,
+ newsocket->hostname,
+ port)))
+ if (!(config =
+ silc_server_config_find_router_conn(server->config,
+ newsocket->ip, port)))
+ if (!(config =
+ silc_server_config_find_router_conn(server->config,
+ newsocket->hostname,
+ port))) {
+ silc_server_disconnect_remote(server, newsocket,
+ "Server closed connection: "
+ "Connection refused");
+ server->stat.conn_failures++;
+ return;
+ }
+
+ /* The connection is allowed */
+
SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
newsocket->ip));
proto_ctx->sock = newsocket;
proto_ctx->rng = server->rng;
proto_ctx->responder = TRUE;
+ proto_ctx->config = config;
/* Prepare the connection for key exchange protocol. We allocate the
protocol but will not start it yet. The connector will be the
context, 60, 0,
SILC_TASK_TIMEOUT,
SILC_TASK_PRI_LOW);
-
- /* Register the connection for network input and output. This sets
- that scheduler will listen for incoming packets for this connection
- and sets that outgoing packets may be sent to this connection as well.
- However, this doesn't set the scheduler for outgoing traffic, it
- will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
- later when outgoing data is available. */
- SILC_REGISTER_CONNECTION_FOR_IO(sock);
}
/* Second part of accepting new connection. Key exchange protocol has been
proto_ctx->responder = TRUE;
proto_ctx->dest_id_type = ctx->dest_id_type;
proto_ctx->dest_id = ctx->dest_id;
+ proto_ctx->config = ctx->config;
/* Free old protocol as it is finished now */
silc_protocol_free(protocol);
case SILC_SOCKET_TYPE_ROUTER:
{
SilcServerEntry new_server;
+ SilcServerConfigSectionServerConnection *conn = ctx->config;
SILC_LOG_DEBUG(("Remote host is %s",
sock->type == SILC_SOCKET_TYPE_SERVER ?
server->stat.servers++;
id_entry = (void *)new_server;
-
- /* There is connection to other server now, if it is router then
- we will have connection to outside world. If we are router but
- normal server connected to us then we will remain standalone,
- if we are standlone. */
+
+ /* Check whether this connection is to be our primary router connection
+ if we dont' already have the primary route. */
if (server->standalone && sock->type == SILC_SOCKET_TYPE_ROUTER) {
+ if (silc_server_config_is_primary_route(server->config) &&
+ !conn->initiator)
+ break;
+
SILC_LOG_DEBUG(("We are not standalone server anymore"));
server->standalone = FALSE;
if (!server->id_entry->router) {
server->router = id_entry;
}
}
+
break;
}
default:
if (server->server_type == SILC_ROUTER) {
/* Route the packet if it is not destined to us. Other ID types but
server are handled separately after processing them. */
- if (packet->dst_id_type == SILC_ID_SERVER &&
+ 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)) {
silc_free(id);
goto out;
}
-
+ }
+
+ /* Parse the incoming packet type */
+ silc_server_packet_parse_type(server, sock, packet);
+
+ if (server->server_type == SILC_ROUTER) {
/* Broadcast packet if it is marked as broadcast packet and it is
originated from router and we are router. */
if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
- packet->flags & SILC_PACKET_FLAG_BROADCAST) {
+ packet->flags & SILC_PACKET_FLAG_BROADCAST &&
+ !server->standalone) {
silc_server_packet_broadcast(server, server->router->connection, packet);
}
}
- /* Parse the incoming packet type */
- silc_server_packet_parse_type(server, sock, packet);
-
out:
/* silc_buffer_clear(sock->inbuf); */
silc_packet_context_free(packet);
argv_types);
silc_server_send_notify_args(server,
server->router->connection,
- server->server_type ==
- SILC_SERVER ? FALSE : TRUE,
+ server->server_type == SILC_SERVER ?
+ FALSE : TRUE,
SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
argc, args);
silc_buffer_free(args);