Possible FreeBSD Jail problem, or other bug in/with FreeRADIUS 2.0.0-pre2
I have an issue with getting my new FreeRADIUS 2.0.0-pre2 server to proxy requests to my old production RADIUS servers. I would appreciate any assistance you might have the time to provide. I am recieving the replies from the old server, but freeradius is throwing them out for some reason. I didn't notice anything more detailed in the radiusd -X output, so here are the log entries. Mon Sep 3 01:52:21 2007 : Proxy: No outstanding request was found for proxy reply from home server old.old.old.old port 1645 - ID 15 Mon Sep 3 01:52:24 2007 : Proxy: No outstanding request was found for proxy reply from home server old.old.old.old port 1645 - ID 15 Mon Sep 3 01:52:27 2007 : Proxy: No outstanding request was found for proxy reply from home server old.old.old.old port 1645 - ID 15 Mon Sep 3 01:52:30 2007 : Proxy: No outstanding request was found for proxy reply from home server old.old.old.old port 1645 - ID 15 Mon Sep 3 01:52:33 2007 : Proxy: No outstanding request was found for proxy reply from home server old.old.old.old port 1645 - ID 15 Mon Sep 3 01:52:41 2007 : Error: Rejecting request 0 due to lack of any response from home server old.old.old.old port 1645 If you want the radiusd -X logs, let me know. I decided to simplify and try just using radclient from the new server and leaving the FreeRADIUS daemon out of it. That also gets replies but radclient throws them out because it doesn't think it sent the request. In the archive, the only prolems I have found with the "radclient: received response to request we did not send." error are due to the reply coming from a different IP or port than that to which the request was sent. That doesn't seem to be the case here. As far as I've been able to tell, all the information appears to be the same between the request and the reply. The new FreeRADIUS server is running under a FreeBSD 6.2 jail configuration, halfway between a chroot and a virtual machine. I don't suspect the system's firewall, but ... There is a stateful firewall on the jail host system, without NAT or redirection. Each jail has it's own routable IP address. I suspect that the jail has a lot to do with the problem. If it can't be worked around, I'm in trouble. In that case I'll try to take it up with the FreeBSD developers to see if they have any ideas, while I scrounge up some seperate hardware to run FreeRADIUS on. newserver$ radclient -f ~/testuser.radclient -r 2 -s -x old.old.old.old:1645 auth pqr7s4z3 Sending Access-Request of id 9 to old.old.old.old port 1645 User-Name = "tstuser" User-Password = "secretpassword" NAS-IP-Address = 255.255.255.255 NAS-Port = 2 Framed-Protocol = PPP rad_recv: Access-Accept packet from host old.old.old.old port 1645, id=9, length=336 radclient: received response to request we did not send. (id=9 socket 3) Sending Access-Request of id 9 to old.old.old.old port 1645 User-Name = "tstuser" User-Password = "secretpassword" NAS-IP-Address = 255.255.255.255 NAS-Port = 2 Framed-Protocol = PPP rad_recv: Access-Accept packet from host old.old.old.old port 1645, id=9, length=336 radclient: received response to request we did not send. (id=9 socket 3) radclient: no response from server for ID 9 socket 3 Total approved auths: 0 Total denied auths: 0 Total lost auths: 1 tcpdump of the request: oldserver# tcpdump -i fxp0 -s 1500 -l host new.new.new.new tcpdump: listening on fxp0 02:29:42.098188 new.new.new.62513 > old.old.old.radius: rad-access-req 65 [id 9] Attr[ User{tstuser} Pass NAS_ipaddr{255.255.255.255} NAS_port{2} Framed_proto{PPP} ] 02:29:42.132898 old.old.old.radius > new.new.new.62513: rad-access-accept 336 [id 9] Attr[ Service_type{Framed} Framed_proto{PPP} Framed_ipnet{255.255.255.255} Vendor_specific{....."................................} Vendor_specific{.....".........=... ..................} Vendor_specific{....."........E.p.. ..................} Vendor_specific{....."........E.p.. ..................} Vendor_specific{....."........AD... ..................} Vendor_specific{....."................................} Vendor_specific{....."................................} Session_timeout{09:00:00 hours} Port_limit{1} Framed_mtu{1500} ] 02:29:45.970121 new.new.new.62513 > old.old.old.radius: rad-access-req 65 [id 9] Attr[ User{tstuser} Pass NAS_ipaddr{255.255.255.255} NAS_port{2} Framed_proto{PPP} ] 02:29:46.024013 old.old.old.radius > new.new.new.62513: rad-access-accept 336 [id 9] Attr[ Service_type{Framed} Framed_proto{PPP} Framed_ipnet{255.255.255.255} Vendor_specific{....."................................} Vendor_specific{.....".........=... ..................} Vendor_specific{....."........E.p.. ..................} Vendor_specific{....."........E.p.. ..................} Vendor_specific{....."........AD... ..................} Vendor_specific{....."................................} Vendor_specific{....."................................} Session_timeout{09:00:00 hours} Port_limit{1} Framed_mtu{1500} ] -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
I decided to simplify and try just using radclient from the new server and leaving the FreeRADIUS daemon out of it. That also gets replies but radclient throws them out because it doesn't think it sent the request.
Ok. Both the server and radclient now use the same code to match replies to requests, so it's expected that they will have the same issues.
I suspect that the jail has a lot to do with the problem.
Try running a test system outside of the jail. If that works, then the problem will at least be narrowed down to the jail.
If it can't be worked around, I'm in trouble. In that case I'll try to take it up with the FreeBSD developers to see if they have any ideas, while I scrounge up some seperate hardware to run FreeRADIUS on.
Or, just install & run it outside of the jail.
tcpdump of the request: ...
That looks OK. Another option is to instrument src/lib/packet.c, function lrad_packet_cmp(). Have it print out WHAT it's comparing, and WHEN it's returning. You'll get a lot of spurious output, but you'll also find out why the reply isn't being matched to a request. It may be that the client is binding to one IP address, and the reply is sent (and seen as received by) another IP address. Alan DeKok.
On Mon, Sep 03, 2007 at 10:52:27AM +0200, Alan DeKok wrote:
Scott Lambert wrote:
I decided to simplify and try just using radclient from the new server and leaving the FreeRADIUS daemon out of it. That also gets replies but radclient throws them out because it doesn't think it sent the request.
Ok. Both the server and radclient now use the same code to match replies to requests, so it's expected that they will have the same issues.
I suspect that the jail has a lot to do with the problem.
Try running a test system outside of the jail. If that works, then the problem will at least be narrowed down to the jail.
tcpdump of the request: ...
That looks OK.
Another option is to instrument src/lib/packet.c, function lrad_packet_cmp(). Have it print out WHAT it's comparing, and WHEN it's returning. You'll get a lot of spurious output, but you'll also find out why the reply isn't being matched to a request.
I've been instrumenting the heck out of anything I thought might be useful. My coding skills are very rusty, but here's what I've come up with. src/lib/packet.c:lrad_packet_cmp() likes the response packet. src/lib/packet.c:lrad_packet_find_by_reply() seems to be failing. radclient appears to be using 0.0.0.0 as the source IP address. lrad_packet_cmp appears to be seeing the source IP address as 69.153.112.27. I haven't figured out how to instrument lrad_hash_table_finddata and the stuff chained from there in a meaningful way. I'm getting lost in the execution path. Based on the above, I changed the listen stanza in radius.conf - ipaddr = * + ipaddr = 69.153.112.27 This permits the server to succesfully proxy requests to other servers. I don't see a way to get radclient to use a specific source IP address. $ ( echo "User-Name = \"testuser1\""; echo "User-Password = \"shhhhh!\""; echo "NAS-IP-Address = 69.153.112.27"; echo "NAS-Port = 1645"; echo "Framed-Protocol = PPP") | ./radclient -r 2 -x 216.61.218.2:1645 auth radius_secret Sending Access-Request of id 233 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "shhhhh!" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=233, length=366 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: lrad_socket_find returned 134591488 lrad_packet_list_find_byreply: ps->inaddr_any false, reply->dst_ipaddr.ipaddr.ip4addr = 0 # the above is the false path of the if statment based on ps->inaddr_any. lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 reply->src_port = 1645 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 0 radclient: received response to request we did not send. (id=233 socket 3) Sending Access-Request of id 233 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "shhhhh!" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=233, length=366 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: lrad_socket_find returned 134591488 lrad_packet_list_find_byreply: ps->inaddr_any false, reply->dst_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 reply->src_port = 1645 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 0 radclient: received response to request we did not send. (id=233 socket 3) lrad_packet_cmp: a->sockfd=3 b->sockfd=3 lrad_packet_cmp: a->id=233 b->id=233 lrad_packet_cmp: a->src_port=62844 b->src_port=62844 lrad_packet_cmp: a->dst_port=1645 b->dst_port=1645 lrad_packet_cmp: a->dst_ipaddr=2 b->dst_ipaddr=47857112 lrad_packet_cmp: a->dst_ipaddr.af=2 b->dst_ipaddr.af=2 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=47857112 b->dst_ipaddr.ipaddr.ip4addr=47857112 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 b->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 lrad_packet_cmp: a->src_ipaddr=2 b->src_ipaddr=460364101 lrad_packet_cmp: a->src_ipaddr.af=2 b->src_ipaddr.af=2 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=460364101 b->src_ipaddr.ipaddr.ip4addr=460364101 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=69.153.112.27 b->src_ipaddr.ipaddr.ip4addr=69.153.112.27 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: a->sockfd=3 b->sockfd=3 lrad_packet_cmp: a->id=233 b->id=233 lrad_packet_cmp: a->src_port=62844 b->src_port=62844 lrad_packet_cmp: a->dst_port=1645 b->dst_port=1645 lrad_packet_cmp: a->dst_ipaddr=2 b->dst_ipaddr=47857112 lrad_packet_cmp: a->dst_ipaddr.af=2 b->dst_ipaddr.af=2 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=47857112 b->dst_ipaddr.ipaddr.ip4addr=47857112 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 b->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 lrad_packet_cmp: a->src_ipaddr=2 b->src_ipaddr=460364101 lrad_packet_cmp: a->src_ipaddr.af=2 b->src_ipaddr.af=2 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=460364101 b->src_ipaddr.ipaddr.ip4addr=460364101 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=69.153.112.27 b->src_ipaddr.ipaddr.ip4addr=69.153.112.27 lrad_packet_cmp: lrad_ipaddr_cmp = 0 radclient: no response from server for ID 233 socket 3 ================================================================= Outside the jail on the same hardware/freeradius binaries, this is what the radclient output looks like: $ ( echo "User-Name = \"testuser1\""; echo "User-Password = \"shhhhh!\""; echo "NAS-IP-Address = 69.153.112.27"; echo "NAS-Port = 16"; echo "Framed-Protocol = PPP") | ./radclient -r 2 -x 216.61.218.2:1645 auth radius_secret Sending Access-Request of id 39 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "shhhhh!" NAS-IP-Address = 69.153.112.27 NAS-Port = 16 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=39, length=366 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: lrad_socket_find returned 134593536 lrad_packet_list_find_byreply: ps->inaddr_any true, ps->ipaddr = 2 # the above is the true path of the if statment based on ps->inaddr_any. lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 reply->src_port = 1645 lrad_packet_cmp: a->sockfd=3 b->sockfd=3 lrad_packet_cmp: a->id=39 b->id=39 lrad_packet_cmp: a->src_port=63507 b->src_port=63507 lrad_packet_cmp: a->dst_port=1645 b->dst_port=1645 lrad_packet_cmp: a->dst_ipaddr=2 b->dst_ipaddr=47857112 lrad_packet_cmp: a->dst_ipaddr.af=2 b->dst_ipaddr.af=2 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=47857112 b->dst_ipaddr.ipaddr.ip4addr=47857112 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 b->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 lrad_packet_cmp: a->src_ipaddr=2 b->src_ipaddr=0 lrad_packet_cmp: a->src_ipaddr.af=2 b->src_ipaddr.af=2 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0 b->src_ipaddr.ipaddr.ip4addr=0 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0.0.0.0 b->src_ipaddr.ipaddr.ip4addr=0.0.0.0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 134571284 lrad_packet_cmp: a->sockfd=3 b->sockfd=3 lrad_packet_cmp: a->id=39 b->id=39 lrad_packet_cmp: a->src_port=63507 b->src_port=63507 lrad_packet_cmp: a->dst_port=1645 b->dst_port=1645 lrad_packet_cmp: a->dst_ipaddr=2 b->dst_ipaddr=47857112 lrad_packet_cmp: a->dst_ipaddr.af=2 b->dst_ipaddr.af=2 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=47857112 b->dst_ipaddr.ipaddr.ip4addr=47857112 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 b->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 lrad_packet_cmp: a->src_ipaddr=2 b->src_ipaddr=0 lrad_packet_cmp: a->src_ipaddr.af=2 b->src_ipaddr.af=2 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0 b->src_ipaddr.ipaddr.ip4addr=0 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0.0.0.0 b->src_ipaddr.ipaddr.ip4addr=0.0.0.0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: a->sockfd=3 b->sockfd=3 lrad_packet_cmp: a->id=39 b->id=39 lrad_packet_cmp: a->src_port=63507 b->src_port=63507 lrad_packet_cmp: a->dst_port=1645 b->dst_port=1645 lrad_packet_cmp: a->dst_ipaddr=2 b->dst_ipaddr=47857112 lrad_packet_cmp: a->dst_ipaddr.af=2 b->dst_ipaddr.af=2 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=47857112 b->dst_ipaddr.ipaddr.ip4addr=47857112 lrad_packet_cmp: a->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 b->dst_ipaddr.ipaddr.ip4addr=216.61.218.2 lrad_packet_cmp: a->src_ipaddr=2 b->src_ipaddr=0 lrad_packet_cmp: a->src_ipaddr.af=2 b->src_ipaddr.af=2 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0 b->src_ipaddr.ipaddr.ip4addr=0 lrad_packet_cmp: a->src_ipaddr.ipaddr.ip4addr=0.0.0.0 b->src_ipaddr.ipaddr.ip4addr=0.0.0.0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 Service-Type = Framed-User ... Do I need to take this to the FreeBSD folks, or is this fixable in FreeRADIUS? -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
I've been instrumenting the heck out of anything I thought might be useful. My coding skills are very rusty, but here's what I've come up with.
src/lib/packet.c:lrad_packet_cmp() likes the response packet. src/lib/packet.c:lrad_packet_find_by_reply() seems to be failing.
OK..
radclient appears to be using 0.0.0.0 as the source IP address. lrad_packet_cmp appears to be seeing the source IP address as 69.153.112.27.
That's pretty much what I expected. radclient doesn't know the IP address, so it sends it from 0.0.0.0. However, the *receiving* code knows the IP, so it gets set.
I haven't figured out how to instrument lrad_hash_table_finddata and the stuff chained from there in a meaningful way. I'm getting lost in the execution path.
Don't worry about that. The code in lrad_packet_find_byreply() SHOULD take care of noticing that the socket was bound to 0.0.0.0, and use that as the source IP address. If it isn't working, it's a bug.
Based on the above, I changed the listen stanza in radius.conf - ipaddr = * + ipaddr = 69.153.112.27
This permits the server to succesfully proxy requests to other servers.
Yes, that will work.
I don't see a way to get radclient to use a specific source IP address.
In CVS head, put "Packet-Src-IP-Address = ..." into the list of attributes to send, along with User-Name. radclient will figure it out. ...
lrad_packet_list_find_byreply: lrad_socket_find returned 134591488 lrad_packet_list_find_byreply: ps->inaddr_any false, reply->dst_ipaddr.ipaddr.ip4addr = 0
That's the problem. The ps->inaddr_any field should be TRUE. ...
Outside the jail on the same hardware/freeradius binaries, this is what the radclient output looks like: ... lrad_packet_list_find_byreply: ps->inaddr_any true, ps->ipaddr = 2
Yup. I'd love to know why that's happening.
Do I need to take this to the FreeBSD folks, or is this fixable in FreeRADIUS?
It MAY be fixable in FreeRADIUS, but I don't have access to a FreeBSD box to test it... I *think* there might be a work-around. Go to lrad_packet_list_socket_add(), and update the following code: if (*((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) ==INADDR_ANY) { ps->inaddr_any = 1; } i.e. add the cast to uint32_t *... Alan DeKok.
On Thu, Sep 13, 2007 at 07:37:14AM +0200, Alan DeKok wrote:
Scott Lambert wrote:
I've been instrumenting the heck out of anything I thought might be useful. My coding skills are very rusty, but here's what I've come up with.
src/lib/packet.c:lrad_packet_cmp() likes the response packet. src/lib/packet.c:lrad_packet_find_by_reply() seems to be failing.
OK..
radclient appears to be using 0.0.0.0 as the source IP address. lrad_packet_cmp appears to be seeing the source IP address as 69.153.112.27.
That's pretty much what I expected. radclient doesn't know the IP address, so it sends it from 0.0.0.0. However, the *receiving* code knows the IP, so it gets set.
The code in lrad_packet_find_byreply() SHOULD take care of noticing that the socket was bound to 0.0.0.0, and use that as the source IP address. If it isn't working, it's a bug.
It MAY be fixable in FreeRADIUS, but I don't have access to a FreeBSD box to test it...
If you *want* access to a FreeBSD box, send me an ssh public key, you can have access to this one until we work this out. I could set you up a jail to play with long term if that would be useful.
I *think* there might be a work-around. Go to lrad_packet_list_socket_add(), and update the following code:
if (*((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) ==INADDR_ANY) { ps->inaddr_any = 1; }
Unfortunately, that didn't change the behavior. I've added some debug prints to lrad_packet_list_socket_add and changed up the printfs in lrad_packet_list_find_byreply. I don't know that they will help. But, just in case.... In jailed client: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_socket: sa->sin_addr = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 64551 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 460364101 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) != INADDR_ANY Sending Access-Request of id 93 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=93, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: lrad_socket_find returned 134833152 lrad_packet_list_find_byreply: ps->inaddr_any = 0 lrad_packet_list_find_byreply: ps->ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->dst_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->src_port = 1645 lrad_packet_list_find_byreply: reply->src_ipaddr.af = 2 lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 0 radclient: received response to request we did not send. (id=93 socket 3) lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 radclient: no response from server for ID 93 socket 3 On jailed client with Packet-Src-IP-Address = jailed client's IP address. radclient: main: radclient_head->request->src_ipaddr.af = 2 radclient: main: client_ipaddr.ipaddr.ip4addr = 460364101, client_port = 0 lrad_socket: sa->sin_addr = 460364101 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 58105 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 460364101 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) != INADDR_ANY Sending Access-Request of id 56 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=56, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_find_byreply: lrad_socket_find returned 134833152 lrad_packet_list_find_byreply: ps->inaddr_any = 0 lrad_packet_list_find_byreply: ps->ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->dst_ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_find_byreply: reply->src_port = 1645 lrad_packet_list_find_byreply: reply->src_ipaddr.af = 2 lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 134570772 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 Service-Type = Framed-User Framed-Protocol = PPP ... On jail host: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_socket: sa->sin_addr = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 65386 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 0 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) == INADDR_ANY Sending Access-Request of id 2 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=2, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: lrad_socket_find returned 134593536 lrad_packet_list_find_byreply: ps->inaddr_any = 1 lrad_packet_list_find_byreply: ps->ipaddr.ipaddr.ip4addr = 1 lrad_packet_list_find_byreply: reply->dst_ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->src_port = 1645 lrad_packet_list_find_byreply: reply->src_ipaddr.af = 2 lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 134571284 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 Service-Type = Framed-User Framed-Protocol = PPP ... On jail host with Packet-Src-IP-Address = jailed client's IP address. radclient: main: radclient_head->request->src_ipaddr.af = 2 radclient: main: client_ipaddr.ipaddr.ip4addr = 460364101, client_port = 0 lrad_socket: sa->sin_addr = 460364101 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 50019 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 460364101 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) != INADDR_ANY Sending Access-Request of id 141 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=141, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_find_byreply: lrad_socket_find returned 134593536 lrad_packet_list_find_byreply: ps->inaddr_any = 0 lrad_packet_list_find_byreply: ps->ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_find_byreply: reply->dst_ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_find_byreply: reply->src_port = 1645 lrad_packet_list_find_byreply: reply->src_ipaddr.af = 2 lrad_packet_list_find_byreply: reply->src_ipaddr.ipaddr.ip4addr = 47857112 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_list_find_byreply: lrad_hash_table_finddata returned 134571284 lrad_packet_cmp: lrad_ipaddr_cmp = 0 lrad_packet_cmp: lrad_ipaddr_cmp = 0 Service-Type = Framed-User Framed-Protocol = PPP ... -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
I've added some debug prints to lrad_packet_list_socket_add and changed up the printfs in lrad_packet_list_find_byreply. I don't know that they will help. But, just in case....
The problem is this:
In jailed client: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_socket: sa->sin_addr = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 64551 lrad_packet_list_socket_add: ps->inaddr_any = 0
That should be 1, not 0. Fix that, and everything else will be OK. Don't bother with printing anything in the packet comparison functions, or the hash functions. They're just innocent bystanders. Figure out WHY lrad_packet_list_socket_add() isn't setting ps->inaddr_any to 1. That's the only relevant issue. Everything else is noise. Alan DeKok.
On Sun, Sep 16, 2007 at 06:46:34PM +0200, Alan DeKok wrote:
Scott Lambert wrote:
In jailed client: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_socket: sa->sin_addr = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 64551 lrad_packet_list_socket_add: ps->inaddr_any = 0
That should be 1, not 0. Fix that, and everything else will be OK. Don't bother with printing anything in the packet comparison functions, or the hash functions. They're just innocent bystanders.
Figure out WHY lrad_packet_list_socket_add() isn't setting ps->inaddr_any to 1. That's the only relevant issue. Everything else is noise.
I'll do my best, but I'm way out in the deep end of the pool. I'm supposed to be over in the wading pool. :-) I think I actually figured it out. I used this reply to trace my logic though the code, and it's probably not important to you, but I figured I would leave it in just in case I'm wrong and maybe you could show me where I went astray. The fix that I've figured out should be attached as src_lib_packet.c.diff. It's a one character change so if it doesn't make it through on the mailing list, it's not a big deal. I do greatly appreciate your assistance with helping me to find the right place to look. I've learned more than I ever thought I would need to know about how to make a network connection in C. I'm just a lowly System Administrator. I usually just try to stay out of the real programmers way. Learning is always a good thing in my book. Here is how I worked it through. lrad_packet_list_socket_add() is called with a pointer to the radius request packet list structure and the socket file descriptor of the socket which has been created with the call to socket() and bound to an IP and port by bind() during the prior call to lrad_socket(). Is that correct?
From radclient.c : /* * Bind to the first specified IP address and port. * This means we ignore later ones. */ if (radclient_head->request->src_ipaddr.af == AF_UNSPEC) { memset(&client_ipaddr, 0, sizeof(client_ipaddr)); client_ipaddr.af = server_ipaddr.af; client_port = 0; } else { client_ipaddr = radclient_head->request->src_ipaddr; client_port = radclient_head->request->src_port; } sockfd = lrad_socket(&client_ipaddr, client_port);
/* I think this looks like: /* lrad_socket( client_ipaddr { .af=AF_INET, .ipaddr.ip4addr=0 }, client_port=0 ) */ if (sockfd < 0) { fprintf(stderr, "radclient: socket: %s\n", librad_errstr); exit(1); } pl = lrad_packet_list_create(1); if (!pl) { fprintf(stderr, "radclient: Out of memory\n"); exit(1); } if (!lrad_packet_list_socket_add(pl, sockfd)) { fprintf(stderr, "radclient: Out of memory\n"); exit(1); } So the ipaddr_any is being set sometime during lrad_socket()? lrad_socket() calls socket() with socket( AF_INET, SOCK_DGRAM, 0 ) because we are only dealing with ipv4 packets in this case. Then, lrad_socket() fills in the sockaddr_in cast sockaddr_storage structure, sa, aka salocal, based on data in lrad_ipaddr_t structure and the port number which were passed as arguments to the function. sa->sin_family = AF_INET; sa->sin_addr = ipaddr->ipaddr.ip4addr; /* aka 0 */ sa->sin_port = htons((uint16_t) port); /* aka 0 */ Then lrad_socket() calls bind() with that information which basically says: "Hey Mr. OpSys, I need to talk to somebody on ipv4. I really don't care what IP and port. Please just hook this socket file descriptor to something." lrad_socket() then returns the sockfd back to the radclient code which sends that off to lrad_packet_list_socket_add(). lrad_packet_list_socket_add() creates a ps structure (packet socket?) which it fills with information from the sockaddr_storage/sockaddr_in structure pointed at by sockfd which was filled in/adjusted by the call to bind(). ? Since this is ipv4 we are going to refer to that sockaddr_in structure as s4. We set the ps->ipaddr.af = AF_INET. We set ps->ipaddr.ipaddr.ip4addr = s4->sin_addr which is the jail's IP address at this point. We set ps->port = ntohs(s4->sin_port) which is some random high port number. I think the only place where ps->ipaddr_any is being set is when we zero out the memory pointed to by ps. The only place we change that value is in the case where ps->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY aka a 32bit 0 value. Tracking through the header files, it looks like ps->ipaddr.ipaddr.ip4addr is the same memory location as ps->ipaddr.ipaddr.ip4addr.s_addr, but that we might need to refer to them individually for portability. s_addr is of type in_addr_t which is a typedef of uint32_t. So I don't think the cast below, which you suggested earlier, should be necessary, on at least this platform. The cast might be more necessary if we were comparing ps->ipaddr.ipaddr.ip4addr to INADDR_ANY. if (*((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) == INADDR_ANY) { ps->inaddr_any = 1; } So, should we be looking for != in the above if() from lrad_packet_list_socket_add()? I flipped that to a != comparison and it seems to work inside or outside the jail with or without specifying the "Packet_Src-IP-Address". Problem solved? Or, is this going to break other things? =================================== jail with Packet-Src-IP-Address: radclient: main: radclient_head->request->src_ipaddr.af = 2 radclient: main: client_ipaddr.ipaddr.ip4addr = 460364101, client_port = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 61397 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 460364101 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) != INADDR_ANY lrad_packet_list_socket_add: ps->inaddr_any = 1 Sending Access-Request of id 238 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=238, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 460364101 Service-Type = Framed-User Framed-Protocol = PPP =================================== jail without Packet-Src-IP-Address: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 51670 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 460364101 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 460364101 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) != INADDR_ANY lrad_packet_list_socket_add: ps->inaddr_any = 1 Sending Access-Request of id 236 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=236, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 Service-Type = Framed-User Framed-Protocol = PPP =================================== host without Packet-Src-IP-Address: radclient: main: radclient_head->request->src_ipaddr.af = 0 radclient: main: client_ipaddr.ipaddr.ip4addr = 0, client_port = 0 lrad_packet_list_socket_add: src.ss_family == AF_INET lrad_packet_list_socket_add: ps->port = 54700 lrad_packet_list_socket_add: ps->inaddr_any = 0 lrad_packet_list_socket_add: ps->ipaddr.af = 2 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr = 0 lrad_packet_list_socket_add: ps->ipaddr.ipaddr.ip4addr.s_addr = 0 lrad_packet_list_socket_add: *((uint32_t *) &ps->ipaddr.ipaddr.ip4addr.s_addr) == INADDR_ANY lrad_packet_list_socket_add: ps->inaddr_any = 0 Sending Access-Request of id 67 to 216.61.218.2 port 1645 User-Name = "testuser1" User-Password = "testpass" NAS-IP-Address = 69.153.112.27 NAS-Port = 1645 Framed-Protocol = PPP rad_recv: Access-Accept packet from host 216.61.218.2 port 1645, id=67, length=336 radclient: recv_one_packet: client_ipaddr.af = 2 radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 Service-Type = Framed-User Framed-Protocol = PPP -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
lrad_packet_list_socket_add() is called with a pointer to the radius request packet list structure and the socket file descriptor of the socket which has been created with the call to socket() and bound to an IP and port by bind() during the prior call to lrad_socket(). Is that correct?
Yes. In the jail, it asks to bind to 0.0.0.0, but the socket *actually* binds to the jail IP. This is why the "inaddr_any" check doesn't match.
So, should we be looking for != in the above if() from lrad_packet_list_socket_add()?
... no. The issue is that when udpfromto is used, we have: a) socket binds to 0.0.0.0 (really, outside of the jail) b) the server doesn't know which IP is used to send a packet c) the server DOES know which IP the response is sent to Since the "received" IP doesn't match the "source" IP, there's a little bit of tweaking that has to be done to match the response to an outstanding request. That's what that check is for.
I flipped that to a != comparison and it seems to work inside or outside the jail with or without specifying the "Packet_Src-IP-Address".
I have no idea why that would work...
Problem solved? Or, is this going to break other things?
It should really break things...
=================================== jail with Packet-Src-IP-Address:
But that tells the server which IP to use for the source IP, so the whole "inaddr_any" checks don't apply. Alan DeKok.
On Tue, Sep 18, 2007 at 09:54:33AM +0200, Alan DeKok wrote:
Scott Lambert wrote:
lrad_packet_list_socket_add() is called with a pointer to the radius request packet list structure and the socket file descriptor of the socket which has been created with the call to socket() and bound to an IP and port by bind() during the prior call to lrad_socket(). Is that correct?
Yes. In the jail, it asks to bind to 0.0.0.0, but the socket *actually* binds to the jail IP. This is why the "inaddr_any" check doesn't match.
So, should we be looking for != in the above if() from lrad_packet_list_socket_add()?
... no. The issue is that when udpfromto is used, we have:
a) socket binds to 0.0.0.0 (really, outside of the jail) b) the server doesn't know which IP is used to send a packet c) the server DOES know which IP the response is sent to
Since the "received" IP doesn't match the "source" IP, there's a little bit of tweaking that has to be done to match the response to an outstanding request. That's what that check is for.
I am sorry for being so dense. I think I can see that I was wrong before. However, what I see, though experimentation and lots of printfs, is that sockfd is bind()ing with a specified IP of 0.0.0.0. bind() takes care of fixing that up for processes in the jail and when bind returns, the socket is *actually* bound to the jail's IP address. Without the jail the socket would have remainded bound to 0.0.0.0. Then lrad_packet_list_socket_add() determines what IP we bound to from the *actual* information in the sockaddr_in structure to which sockfd points. That is the &ps->ipaddr.ipaddr.ip4addr.s_addr inside lrad_packet_list_socket_add(). In the jail that is actually the jail's IP address. That's all well and good. However, perhaps the problem comes when we get to recv_one_packet() in radclient.c and unconditionally set reply->dst_ipaddr = client_ipaddr which is apparantly due to "udpfromto issues." /* * udpfromto issues. We may have bound to "*", * and we want to find the replies that are sent to * (say) 127.0.0.1. */ reply->dst_ipaddr = client_ipaddr; Commenting that line out makes my jail work. On my systems, reply->dst_ipaddr == client_ipaddr except when Packet-Src-IP-Address is NOT specified within the jail. When Packet-Src-IP-Address is NOT specified within the jail: radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 radclient: recv_one_packet: reply->dst_ipaddr.ipaddr.ip4addr = 460364101 By leaving reply->dst_ipaddr alone, lrad_packet_list_find_byreply is able to match the ps->ipaddr with the reply->dst_ipaddr even though ps->inaddr_any = 0. I don't know the circumstances in which reply->dst_ipaddr != client_ipaddr in such a way that it would be necessary to force them ==. Are those circumstances mutually exclusive of the jail circumstances? Could this be the correct location for a fix? -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
I just wanted to ping the list just in case my last message had been caught in a spam filter or otherwise missed. I'm not trying to be pushy, just don't want to get into a situation where everyone is waiting on a response from everyone else. Just want to make sure I'm the only one waiting. :-) I have no expectation that anybody "owes" me a response. If I need to look deeper into the problem on my own, I will be happy to do so. If I have, once again, picked on a piece of the code that has no bearing in my issue, please don't be afraid to tell me I am being stupid. If I need to switch this to the -devel list, I can subscribe and repost it there. This may have gone a bit off charter for the -users list. On Tue, Sep 18, 2007 at 05:17:27PM -0500, Scott Lambert wrote:
On Tue, Sep 18, 2007 at 09:54:33AM +0200, Alan DeKok wrote:
Scott Lambert wrote:
lrad_packet_list_socket_add() is called with a pointer to the radius request packet list structure and the socket file descriptor of the socket which has been created with the call to socket() and bound to an IP and port by bind() during the prior call to lrad_socket(). Is that correct?
Yes. In the jail, it asks to bind to 0.0.0.0, but the socket *actually* binds to the jail IP. This is why the "inaddr_any" check doesn't match.
So, should we be looking for != in the above if() from lrad_packet_list_socket_add()?
... no. The issue is that when udpfromto is used, we have:
a) socket binds to 0.0.0.0 (really, outside of the jail) b) the server doesn't know which IP is used to send a packet c) the server DOES know which IP the response is sent to
Since the "received" IP doesn't match the "source" IP, there's a little bit of tweaking that has to be done to match the response to an outstanding request. That's what that check is for.
I am sorry for being so dense. I think I can see that I was wrong before.
However, what I see, though experimentation and lots of printfs, is that sockfd is bind()ing with a specified IP of 0.0.0.0. bind() takes care of fixing that up for processes in the jail and when bind returns, the socket is *actually* bound to the jail's IP address. Without the jail the socket would have remainded bound to 0.0.0.0.
Then lrad_packet_list_socket_add() determines what IP we bound to from the *actual* information in the sockaddr_in structure to which sockfd points. That is the &ps->ipaddr.ipaddr.ip4addr.s_addr inside lrad_packet_list_socket_add(). In the jail that is actually the jail's IP address.
That's all well and good. However, perhaps the problem comes when we get to recv_one_packet() in radclient.c and unconditionally set reply->dst_ipaddr = client_ipaddr which is apparantly due to "udpfromto issues."
/* * udpfromto issues. We may have bound to "*", * and we want to find the replies that are sent to * (say) 127.0.0.1. */ reply->dst_ipaddr = client_ipaddr;
Commenting that line out makes my jail work.
On my systems, reply->dst_ipaddr == client_ipaddr except when Packet-Src-IP-Address is NOT specified within the jail.
When Packet-Src-IP-Address is NOT specified within the jail:
radclient: recv_one_packet: client_ipaddr.ipaddr.ip4addr = 0 radclient: recv_one_packet: reply->dst_ipaddr.ipaddr.ip4addr = 460364101
By leaving reply->dst_ipaddr alone, lrad_packet_list_find_byreply is able to match the ps->ipaddr with the reply->dst_ipaddr even though ps->inaddr_any = 0.
I don't know the circumstances in which reply->dst_ipaddr != client_ipaddr in such a way that it would be necessary to force them ==.
Are those circumstances mutually exclusive of the jail circumstances?
Could this be the correct location for a fix?
-- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
If I need to look deeper into the problem on my own, I will be happy to do so. If I have, once again, picked on a piece of the code that has no bearing in my issue, please don't be afraid to tell me I am being stupid.
I don't think I have any issues doing that... ...
That's all well and good. However, perhaps the problem comes when we get to recv_one_packet() in radclient.c and unconditionally set reply->dst_ipaddr = client_ipaddr which is apparantly due to "udpfromto issues."
/* * udpfromto issues. We may have bound to "*", * and we want to find the replies that are sent to * (say) 127.0.0.1. */ reply->dst_ipaddr = client_ipaddr;
Commenting that line out makes my jail work.
OK, I see why that works for radclient. I recall, though, that the original issue you ran into was with proxying. Do you still have an issue with that, or does this one-line fix address everything? Alan DeKok.
On Fri, Sep 21, 2007 at 05:02:43PM +0200, Alan DeKok wrote:
Scott Lambert wrote:
If I need to look deeper into the problem on my own, I will be happy to do so. If I have, once again, picked on a piece of the code that has no bearing in my issue, please don't be afraid to tell me I am being stupid.
I don't think I have any issues doing that...
:-)
...
That's all well and good. However, perhaps the problem comes when we get to recv_one_packet() in radclient.c and unconditionally set reply->dst_ipaddr = client_ipaddr which is apparantly due to "udpfromto issues."
/* * udpfromto issues. We may have bound to "*", * and we want to find the replies that are sent to * (say) 127.0.0.1. */ reply->dst_ipaddr = client_ipaddr;
Commenting that line out makes my jail work.
OK, I see why that works for radclient. I recall, though, that the original issue you ran into was with proxying. Do you still have an issue with that, or does this one-line fix address everything?
I've been expecting that there would be a similar chunk of code in the server that I could go find if you thought I was on the right track. I have not had sufficient confidence in my code reading to trust my changes to the now semi-production server. I would not expect that code in radclient.c could fix radiusd. I've been wrong before. I've been using radclient to debug because you indicated that it used the same library for matching up packets. If the above is legitimately the bug I was looking for, I'll have to solve the proxy issue seperately, but with a better idea of what I am looking for. I will do my homework, look for a similar line in the daemon code, and get back to you, hopefully tonight or tomorrow. -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
I've been expecting that there would be a similar chunk of code in the server that I could go find if you thought I was on the right track.
Unfortunately, there isn't.
I would not expect that code in radclient.c could fix radiusd. I've been wrong before.
It won't.
I've been using radclient to debug because you indicated that it used the same library for matching up packets. If the above is legitimately the bug I was looking for, I'll have to solve the proxy issue seperately, but with a better idea of what I am looking for.
Or, simply tell the server to "listen" on the jail IP address. That will solve the problem, without code changes. One patch which *would* help is the ability to set the source IP address for proxying. It's likely not difficult to do, but the code hasn't been written yet. Alan DeKok.
On Sat, Sep 22, 2007 at 04:59:25AM +0200, Alan DeKok wrote:
Scott Lambert wrote:
I've been expecting that there would be a similar chunk of code in the server that I could go find if you thought I was on the right track.
Unfortunately, there isn't.
Okay, I'm not going crazy then...
I've been using radclient to debug because you indicated that it used the same library for matching up packets. If the above is legitimately the bug I was looking for, I'll have to solve the proxy issue seperately, but with a better idea of what I am looking for.
Or, simply tell the server to "listen" on the jail IP address. That will solve the problem, without code changes.
Yeah, I'm running with that workaround. I was just hoping I wouldn't have to maintain config differences between the multiple server instances. But it's definitely acceptable.
One patch which *would* help is the ability to set the source IP address for proxying. It's likely not difficult to do, but the code hasn't been written yet.
I'm speaking from ignorance here. Could the server do the bind calls for the listen sockets and check to see if the bound IP is the same as the one specified in the bind call and if not, update the server to use the bound IP rather than the configured IP at least in the case of listen { ipaddr = * }. pseudo code: server_addr = read_from_config_file; bind (sockfd, {listensocketinfo} ); if ( server_addr == INADDR_ANY && sockfd->ipaddr != server_addr ) { server_addr = fd->ipaddr; } At that point, would the existing code work alright for this wierd and "wonderful" jail environment without breaking other environments? I suspect it might not be workable due to the udpfromto stuff. I think this is the last message I will bother you with on this topic. My problem is resolved by specifying the IP address in the config file and doing anything more generic is probably beyond my skills at this point. Thank you for your time and patience. -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
Could the server do the bind calls for the listen sockets and check to see if the bound IP is the same as the one specified in the bind call and if not, update the server to use the bound IP rather than the configured IP at least in the case of listen { ipaddr = * }.
Yes. Try the attached patch. It seems to work, but test it for yourself.
Thank you for your time and patience.
My patience is often a reflection of the effort I see people putting into solving the problems they see. Alan DeKok.
On Mon, Sep 24, 2007 at 03:57:36PM +0200, Alan DeKok wrote:
Scott Lambert wrote:
Could the server do the bind calls for the listen sockets and check to see if the bound IP is the same as the one specified in the bind call and if not, update the server to use the bound IP rather than the configured IP at least in the case of listen { ipaddr = * }.
Yes. Try the attached patch. It seems to work, but test it for yourself.
You are good. :-) Worked the first time. Without the patch, jail environment, default config: Initializing the thread pool... Listening on authentication address * port 1812 Listening on accounting address * port 1813 Listening on proxy address * port 1814 Ready to process requests. With the patch, jail environment, default config: Initializing the thread pool... Listening on authentication address 10.0.0.25 port 1812 Listening on accounting address 10.0.0.25 port 1813 Listening on proxy address 10.0.0.25 port 1814 Ready to process requests. Proxied the requests correctly. I also build it in a non-jailed environment to make sure it still listened on *. With the patch, non-jail environment, default config: Initializing the thread pool... Listening on authentication address * port 1812 Listening on accounting address * port 1813 Listening on proxy address * port 1814 Ready to process requests. Looks like a winner to me. Is this something you are willing to add to the codebase or should the FreeBSD port track this patch, and the one for radclient.c? Thank you again! -- Scott Lambert KC5MLE Unix SysAdmin lambert@lambertfam.org
Scott Lambert wrote:
Is this something you are willing to add to the codebase or should the FreeBSD port track this patch, and the one for radclient.c?
I've added it to CVS. Alan DeKok.
participants (2)
-
Alan DeKok -
Scott Lambert