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