+ client = client_find(clients, ipaddr,sock->proto);
+ if (!client) {
+ char name[256], buffer[128];
+
+#ifdef WITH_DYNAMIC_CLIENTS
+ unknown: /* used only for dynamic clients */
+#endif
+
+ /*
+ * DoS attack quenching, but only in daemon mode.
+ * If they're running in debug mode, show them
+ * every packet.
+ */
+ if (debug_flag == 0) {
+ static time_t last_printed = 0;
+
+ now = time(NULL);
+ if (last_printed == now) return NULL;
+
+ last_printed = now;
+ }
+
+ listener->print(listener, name, sizeof(name));
+
+ radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
+#ifdef WITH_TCP
+ " proto %s"
+#endif
+ , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
+ buffer, sizeof(buffer)), src_port
+#ifdef WITH_TCP
+ , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
+#endif
+ );
+ return NULL;
+ }
+
+#ifndef WITH_DYNAMIC_CLIENTS
+ return client; /* return the found client. */
+#else
+
+ /*
+ * No server defined, and it's not dynamic. Return it.
+ */
+ if (!client->client_server && !client->dynamic) return client;
+
+ now = time(NULL);
+
+ /*
+ * It's a dynamically generated client, check it.
+ */
+ if (client->dynamic && (src_port != 0)) {
+ /*
+ * Lives forever. Return it.
+ */
+ if (client->lifetime == 0) return client;
+
+ /*
+ * Rate-limit the deletion of known clients.
+ * This makes them last a little longer, but
+ * prevents the server from melting down if (say)
+ * 10k clients all expire at once.
+ */
+ if (now == client->last_new_client) return client;
+
+ /*
+ * It's not dead yet. Return it.
+ */
+ if ((client->created + client->lifetime) > now) return client;
+
+ /*
+ * This really puts them onto a queue for later
+ * deletion.
+ */
+ client_delete(clients, client);
+
+ /*
+ * Go find the enclosing network again.
+ */
+ client = client_find(clients, ipaddr, sock->proto);
+
+ /*
+ * WTF?
+ */
+ if (!client) goto unknown;
+ if (!client->client_server) goto unknown;
+
+ /*
+ * At this point, 'client' is the enclosing
+ * network that configures where dynamic clients
+ * can be defined.
+ */
+ rad_assert(client->dynamic == 0);
+
+ } else if (!client->dynamic && client->rate_limit) {
+ /*
+ * The IP is unknown, so we've found an enclosing
+ * network. Enable DoS protection. We only
+ * allow one new client per second. Known
+ * clients aren't subject to this restriction.
+ */
+ if (now == client->last_new_client) goto unknown;
+ }
+
+ client->last_new_client = now;
+
+ request = request_alloc();
+ if (!request) goto unknown;
+
+ request->listener = listener;
+ request->client = client;
+ request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
+ if (!request->packet) { /* badly formed, etc */
+ request_free(&request);
+ goto unknown;
+ }
+ request->reply = rad_alloc_reply(request->packet);
+ if (!request->reply) {
+ request_free(&request);
+ goto unknown;
+ }
+ request->packet->timestamp = request->timestamp;
+ request->number = 0;
+ request->priority = listener->type;
+ request->server = client->client_server;
+ request->root = &mainconfig;
+
+ /*
+ * Run a fake request through the given virtual server.
+ * Look for FreeRADIUS-Client-IP-Address
+ * FreeRADIUS-Client-Secret
+ * ...
+ *
+ * and create the RADCLIENT structure from that.
+ */
+ DEBUG("server %s {", request->server);
+
+ rcode = module_authorize(0, request);
+
+ DEBUG("} # server %s", request->server);
+
+ if (rcode != RLM_MODULE_OK) {
+ request_free(&request);
+ goto unknown;
+ }
+
+ /*
+ * If the client was updated by rlm_dynamic_clients,
+ * don't create the client from attribute-value pairs.
+ */
+ if (request->client == client) {
+ created = client_create(clients, request);
+ } else {
+ created = request->client;
+
+ /*
+ * This frees the client if it isn't valid.
+ */
+ if (!client_validate(clients, client, created)) goto unknown;
+ }
+ request_free(&request);
+
+ if (!created) goto unknown;
+
+ return created;
+#endif