How can I write a multi-homed server?

How can I write a multi-homed server?

  The original question was actually from Shankar Ramamoorthy
  (shankar@viman.com):

       I want to run a server on a multi-homed host. The host is
       part of two networks and has two ethernet cards. I want to
       run a server on this machine, binding to a pre-determined
       port number. I want clients on either subnet to be able to
       send broadcast packates to the port and have the server
       receive them.

  And answered by Andrew Gierth (andrew@erlenstar.demon.co.uk):

  Your first question in this scenario is, do you need to know which
  subnet the packet came from? I'm not at all sure that this can be
  reliably determined in all cases.

  If you don't really care, then all you need is one socket bound to
  INADDR_ANY. That simplifies things greatly.

  If you do care, then you have to bind multiple sockets. You are
  obviously attempting to do this in your code as posted, so I'll assume
  you do.

       I was hoping that something like the following would work.
       Will it?  This is on Sparcs running Solaris 2.4/2.5.

  I don't have access to Solaris, but I'll comment based on my
  experience with other Unixes.

  [Shankar's original code omitted]

  What you are doing is attempting to bind all the current hosts unicast
  addresses as listed in hosts/NIS/DNS. This may or may not reflect
  reality, but much more importantly, neglects the broadcast addresses.
  It seems to be the case in the majority of implementations that a
  socket bound to a unicast address will not see incoming packets with
  broadcast addresses as their destinations.

  The approach I've taken is to use SIOCGIFCONF to retrieve the list of
  active network interfaces, and SIOCGIFFLAGS and SIOCGIFBRDADDR to
  identify broadcastable interfaces and get the broadcast addresses.
  Then I bind to each unicast address, each broadcast address, and to
  INADDR_ANY as well. That last is necessary to catch packets that are
  on the wire with INADDR_BROADCAST in the destination.  (SO_REUSEADDR
  is necessary to bind INADDR_ANY as well as the specific addresses.)

  This gives me very nearly what I want. The wrinkles are:

  o  I don't assume that getting a packet through a particular socket
     necessarily means that it actually arrived on that interface.

  o  I can't tell anything about which subnet a packet originated on if
     its destination was INADDR_BROADCAST.

  o  On some stacks, apparently only those with multicast support, I get
     duplicate incoming messages on the INADDR_ANY socket.



Home
FAQ