On 04.04.2014 22:23, Alan DeKok wrote:
Re-inventing the wheel is a lot of work. Sometimes you can make a mistake.
Yes, it is possible. The problem is that delay occurs before this code starts. I will explain how can this happen lower.
But FreeRADIUS dhcp module thinks that all requests from the same source are request from single client. This is plain wrong in case of DHCP relay in between DHCP clients and FreeRADIUS that is located in an isolated vlan.
I don't see how that's a problem. The DHCP code doesn't use client definitions. The server core doesn't queue requests by client.
The DHCP code does DOES use "client definitions". There is a comment in src/lib/dhcp.c before the code I'm speaking about: /* * Create a unique vector from the MAC address and the * DHCP opcode. This is a hack for the RADIUS * infrastructure in the rest of the server. * * Note: packet->data[2] == 6, which is smaller than * sizeof(packet->vector) * * FIXME: Look for client-identifier in packet, * and use that, too? */ memset(packet->vector, 0, sizeof(packet->vector)); memcpy(packet->vector, packet->data + 28, packet->data[2]); packet->vector[packet->data[2]] = packet->code & 0xff; This is plain wrong as it's making non-unique "vector" when all requests come from the same MAC address of the DHCP relay.
So, FreeRADIUS queues requests and does not pass them to rlm_perl instantly as it should. 6 seconds is delay between DHCP request arrival to the box via network interface and invoke of post_auth perl function.
So... what, FreeRADIUS does *nothing* with the packets for 6 seconds? That doesn't make sense.
No, it does something. It drops some requests. In detail: 1. New client sends DHCP Discover via DHCP relay with new xid. 2. FreeRADIUS has plenty of requests from this DHCP relay and drops the request with a note in its log about duplicate request. That's a monent when it fails. 3. Client does not sit silent and repeats its request with the same xid several times. 4. Eventually, the request with noted xid comes in such a moment that FreeRAIDUS accepts it without a drop and passes to post_auth(). There are 6 seconds between point 1 and point 4 generally and several retransmissions from the DHCP clients with the same xid.
When the server receives a packet, the packet gets put onto a queue.
Or dropped as "duplicate".
The queue is ordered, so first-in, first-out. The queue doesn't care whether the packet is RADIUS, DHCP, VMPS, or which client the packet came from.
When a thread is done with one request, it pulls the next one from the queue. Again, the thread doesn't care what kind of packet it is, or which client it came from.
Yes.
The ONLY reason for the server to block is if all threads are unresponsive. The ONLY reason that the threads become unresponsive is if they're doing some non-default action... which blocks the server.
No-no, we are not talking about server "blocking".
Basically, I'd like dhcp module running mode in which it would pass ALL requests to rlm_perl without duplicate checks and queueing as I perform thread-safe in-memory caching of results distinguishing cliens using DHCP Option 82 details.
It's not doing duplicate checks.
FreeRADIUS core does.
Or, another mode of dhcp module in which it would be able to check existance of the Option 82 in the request and use it to no treat requests from distinct clients as coming from single source.
The DHCP module does NOT do that. I have no idea why you think it does.
I known it does not do that. I wish it would :-)
Honestly, try using the "mac2ip" module. Pull the MACs and IPs from your database. and put them into the mac2ip file. Configure the mac2ip module, and disable your Perl script.
You will see that the response time of FreeRADIUS drop to 40ms or so. It will be able to do about 10K DHCP packets per second.
Our business logic is not so straight-forward and considers all of source data in the DHCP option 82 and lots of additional data in the database to decide if this client should get ACK or NAK and which pool should be used for this particular request and should client get IP/mask only or gateway/DNS too etc. etc. It makes many complex decisions and makes them very fast for hundreds of requests in parallel. Eugene Grosbein