+ /* Ignore packets from disabled connection */
+ if (idata->status & SILC_IDLIST_STATUS_DISABLED &&
+ packet->type != SILC_PACKET_HEARTBEAT &&
+ packet->type != SILC_PACKET_RESUME_ROUTER &&
+ packet->type != SILC_PACKET_REKEY)
+ return FALSE;
+
+ /* Check that the the current client ID is same as in the client's packet. */
+ if (idata->conn_type == SILC_CONN_CLIENT) {
+ SilcClientEntry client = (SilcClientEntry)silc_packet_get_context(stream);
+ SilcClientID client_id;
+
+ if (client->id && packet->src_id &&
+ silc_id_str2id(packet->src_id, packet->src_id_len,
+ packet->src_id_type, &client_id, sizeof(client_id))) {
+ if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) {
+ SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s",
+ silc_get_packet_name(packet->type)));
+ return FALSE;
+ }
+ }
+ }
+
+ 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 &&
+ !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
+ packet->dst_id_type == SILC_ID_SERVER &&
+ idata->conn_type != SILC_CONN_CLIENT &&
+ memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
+ SilcPacketStream conn;
+ SilcServerID server_id;
+
+ silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
+ &server_id, sizeof(server_id));
+
+ conn = silc_server_route_get(server, &server_id, SILC_ID_SERVER);
+ if (!conn) {
+ SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
+ silc_id_render(&server_id, SILC_ID_SERVER)));
+ return FALSE;
+ }
+
+ silc_server_packet_route(server, conn, packet);
+ silc_packet_free(packet);
+ return TRUE;
+ }
+ }
+
+ /* Broadcast packet if it is marked as broadcast packet and it is
+ originated from router and we are router. */
+ if (server->server_type == SILC_ROUTER &&
+ idata->conn_type == SILC_CONN_ROUTER &&
+ packet->flags & SILC_PACKET_FLAG_BROADCAST) {
+ /* Broadcast to our primary route */
+ silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
+
+ /* If we have backup routers then we need to feed all broadcast
+ data to those servers. */
+ silc_server_backup_broadcast(server, stream, packet);
+ }
+