Brian Candler wrote:
I have found some odd behaviour to do with proxying and retransmissions with rlm_replicate (specifically accounting packets)
Accounting packets are almost never retransmitted. They SHOULD have an Acct-Delay-Time attribute, to signal delays between creation of the data, and sending of the packet. This attribute changes on every delayed (re)-transmission. So the packets are never retransmitted unchanged.
I set up a proxy config, where I also happen to modify the packet.
preacct { ... Proxy-To-Realm := "handover"
Well, "update config", but I get your point.
As well as proxying, rlm_replicate is used to feed the accounting packets elsewhere:
accounting { sql_log ... replicate # using rlm_replicate and Replicate-To-Realm }
Now, if the "handover" home servers are down, and I send a test packet with retransmissions using
echo -e 'User-Name="briantest"\nEvent-Timestamp=1342099825\nFramed-IP-Address=1.2.3.4\nAcct-Status-Type=Interim-Update' | radclient -r3 -t3 -x localhost:1813 acct testing123
what I find is:
* just the first packet is written to the sql_log (that's fine) * For the second and third packets, freeradius -X just shows "Discarding duplicate request from client localhost port 36957 - ID: 146"
Well, no. The message (from the source code) is: radlog(L_ERR, "Discarding duplicate request from " "client %s port %d - ID: %u due to unfinished request %u" This means that the server is still processing the request. It was NOT proxied. Or, it has been proxied, and a reply was received.
After that, freeradius says "Rejecting request 0 (proxy Id 181) due to lack of any response from home server 192.0.2.1 port 1813" * all three packets are replicated.
Well, no. If you see that, it's because of something else. See the debug log. The source code does this: packet_p = fr_packet_list_find(pl, packet); if (packet_p) { request = fr_packet2myptr(REQUEST, packet, packet_p); rad_assert(request->in_request_hash); if ((request->packet->data_len == packet->data_len) && (memcmp(request->packet->vector, packet->vector, sizeof(packet->vector)) == 0)) { received_retransmit(request, client); return 0; } i.e. find the packet by code, src/dst IP, src/dst port. If found, check if the new packet is IDENTICAL to one we've already seen. If so, call a function which logs the error above. Then, STOP processing the packet. So NO modules are called on retransmits. This is a hard requirement of the server.
The second and third replica packets are missing the Reply-Message attribute
<shrug> See the debug log for why.
It's this last bit which I think is odd. Shouldn't the replicate also be suppressed for retransmissions?
Yes. As ALWAYS, see the FULL debug log for details. Alan DeKok.