[PATCH] Support more than 2 NICs and half-way end-point support
Jules Colding <[email protected]> Mon, 17 Sep 2007 14:24:11 +0200
| Newsgroups | gmane.comp.gnome.orbit.general |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've run across a situation where I needed to put my externally visible object on a specific interface. I have more than 2 NIC in the box, but the current behavior of ORBit2 is to simply use the first non "127.0.0.1" NIC. Consequently I decided to hack a little and came up with the patch below. It expands on the ORBNetID functionality by allowing the user to specify the NIC to be used by linc2 when exposing objects to the network. This is not end-point functionality but is is a small step in that direction. We only need a way to specify the port number too for complete end-point functionality. I've also removed the artificial limitation to 2 NICs and will use SIOCGIFNUM if supported to determine the number of present NICs. Failure to use SIOCGIFNUM will fallback to a #define with the value of 32 just to be on the safe side. Please comment. Thanks, jules Index: src/orb/orb-core/corba-orb.c =================================================================== --- src/orb/orb-core/corba-orb.c (revision 2024) +++ src/orb/orb-core/corba-orb.c (working copy) @@ -101,6 +101,7 @@ link_use_local_hostname (LINK_NET_ID_IS_IPADDR); break; } + link_set_local_hostname(orbit_net_id); } while (0); } Index: linc2/include/linc/linc-protocol.h =================================================================== --- linc2/include/linc/linc-protocol.h (revision 2024) +++ linc2/include/linc/linc-protocol.h (working copy) @@ -74,7 +74,8 @@ LINK_NET_ID_IS_LOCAL, LINK_NET_ID_IS_SHORT_HOSTNAME, LINK_NET_ID_IS_FQDN, - LINK_NET_ID_IS_IPADDR + LINK_NET_ID_IS_IPADDR, + LINK_NET_ID_IS_CUSTOM } LinkNetIdType; @@ -84,6 +85,7 @@ char *link_get_tmpdir (void); void link_set_tmpdir (const char *dir); void link_use_local_hostname (LinkNetIdType use); +void link_set_local_hostname (const char *host_id); const char* link_get_local_hostname (void); G_END_DECLS Index: linc2/ChangeLog =================================================================== --- linc2/ChangeLog (revision 2024) +++ linc2/ChangeLog (working copy) @@ -1,3 +1,14 @@ +2007-09-17 Jules Colding <[email protected]> + + * include/linc/linc-protocol.h (enum): LinkNetIdType expanded + with one more value. This value will request that ORBit2 is using + a specific NIC when creating network visible objects. + + * src/linc-protocols.c (get_netid): Support more than 2 NICs. + Implement the new LINK_NET_ID_IS_CUSTOM functionality. + (link_set_local_hostname): Will set the requested NIC as the + one that is chosen when an object is bound to an interface. + ======================== ORBit2-2.14.9 ==================== 2007-08-14 Jules Colding <[email protected]> Index: linc2/src/linc-protocols.c =================================================================== --- linc2/src/linc-protocols.c (revision 2024) +++ linc2/src/linc-protocols.c (working copy) @@ -31,6 +31,7 @@ static char *link_tmpdir = NULL; static LinkNetIdType use_local_host = LINK_NET_ID_IS_FQDN; +static const char *fixed_host_net_id = NULL; /* * make_local_tmpdir: @@ -134,6 +135,12 @@ #if defined(AF_INET) || defined(AF_INET6) || defined (AF_UNIX) +/* hopefully a sufficiently large default NIC count */ +#ifdef DEFAULT_LINC2_IFNUM +#undef DEFAULT_LINC2_IFNUM +#endif +#define DEFAULT_LINC2_IFNUM (32) + static char * get_netid(LinkNetIdType which, char *buf, @@ -142,34 +149,59 @@ if (LINK_NET_ID_IS_LOCAL == which) return strncpy(buf, "localhost", len); - if (LINK_NET_ID_IS_IPADDR == which) { + if ((LINK_NET_ID_IS_IPADDR == which) + || (LINK_NET_ID_IS_CUSTOM == which)) { #ifndef G_OS_WIN32 struct sockaddr_in *adr = NULL; - struct ifreq my_ifreqs[2]; - struct ifconf my_ifconf; - int num, i, sock; + struct ifreq *my_ifreqs = NULL; + struct ifconf my_ifconf = { 0 }; + int sock = -1; + int num = 0; + int i = 0; - my_ifconf.ifc_len = sizeof(my_ifreqs); - my_ifconf.ifc_req = my_ifreqs; sock = socket(AF_INET,SOCK_DGRAM,0); if (-1 == sock) goto out; - +#ifdef SIOCGIFNUM + i = ioctl(sock, SIOCGIFNUM, &num); + if ((0 > i) || !num) { + close(sock); + goto out; + } +#else + num = DEFAULT_LINC2_IFNUM; +#endif + my_ifconf.ifc_len = sizeof(struct ifreq) * num; + my_ifconf.ifc_req = (struct ifreq*)malloc(my_ifconf.ifc_len); + if (!my_ifconf.ifc_req) { + close(sock); + goto out; + } if (ioctl(sock,SIOCGIFCONF,&my_ifconf) < 0) { close(sock); + free(my_ifconf.ifc_req); goto out; } close(sock); - num = my_ifconf.ifc_len / sizeof(struct ifreq); - if (!num) - goto out; - + my_ifreqs = my_ifconf.ifc_req; for (i = 0; i < num; i++) { adr = (struct sockaddr_in *)&my_ifreqs[i].ifr_ifru.ifru_addr; - if (strcmp("127.0.0.1", inet_ntoa(adr->sin_addr))) + if (fixed_host_net_id) { + if (!strcmp(fixed_host_net_id, inet_ntoa(adr->sin_addr))) + break; + } else { + if (strcmp("127.0.0.1", inet_ntoa(adr->sin_addr))) + break; + } + if (!strcmp("0.0.0.0", inet_ntoa(adr->sin_addr))) { + if (i) + adr = (struct sockaddr_in *)&my_ifreqs[--i].ifr_ifru.ifru_addr; break; + } } + free(my_ifconf.ifc_req); + /* will be 127.0.0.1 anyway, if no other address is defined... */ return strncpy(buf, (const char*)inet_ntoa(adr->sin_addr), len); #else @@ -178,8 +210,10 @@ /* Let's hope 20 interfaces is enough. There doesn't * seem to be any way to get information about how * many interfaces there are. + * + * [Jules] Using the ifnum define instead... */ - INTERFACE_INFO interfaces[20]; + INTERFACE_INFO interfaces[DEFAULT_LINC2_IFNUM]; int i; sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -282,6 +316,16 @@ use_local_host = use; } +void +link_set_local_hostname (const char *host_id) +{ + if (!host_id || !strlen(host_id)) + return; + + fixed_host_net_id = host_id; + use_local_host = LINK_NET_ID_IS_CUSTOM; +} + /* * True if succeeded in mapping, else false. */ Index: ChangeLog =================================================================== --- ChangeLog (revision 2024) +++ ChangeLog (working copy) @@ -1,3 +1,37 @@ +2007-09-17 Jules Colding <[email protected]> + + * ORBit2: It is now possible to use the ORBNetID command + line option to specify a specific NIC to be used by ORBit2 + when creating externally visible objects. This is supported + by adding LINK_NET_ID_IS_CUSTOM to the LinkNetIdType enum + type. Previously the first NIC which wasn't "127.0.0.1" was + unconditionally used. + + The ORBNetID argument must be of a format that is compatible + to the address format that is returned by inet_ntoa(3) on a + return value of the SIOCGIFCONF ioctl. A specific IP address, + such as '192.168.2.45', would be an acceptable format. + + The previous behavior of just using the first non "127.0.0.1" + NIC is maintained if the net id isn't LINK_NET_ID_IS_CUSTOM. + + If, on the other hand, the net id is LINK_NET_ID_IS_CUSTOM then + the used NIC will be: + + 1) The net id specified but only if it is found in the interface + list as returned by SIOCGIFCONF. + + 2) If the requested net id isn't found in the list then it will + be the last non "0.0.0.0" addressed NIC in said list. This may + or may not be "127.0.0.1". + + I considered if we should use assert() if the specified net id + isn't found or if it is invalid, but I decided against it on the + grounds that not doing so is more in line with current behavior. + + * src/orb/orb-core/corba-orb.c (ORBit_ORB_start_servers): + Support the new LINK_NET_ID_IS_CUSTOM functionality + ==================== ORBit2-2.14.9 ===================== 2007-09-17 Kjartan Maraas <[email protected]>