Possible FreeBSD Jail problem, or other bug in/with FreeRADIUS 2.0.0-pre2
Scott Lambert
lambert at lambertfam.org
Wed Sep 19 00:17:27 CEST 2007
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 at lambertfam.org
More information about the Freeradius-Users
mailing list