[PATCH] Support more than 2 NICs and half-way end-point support



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  <colding omesc com>
+
+	* 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  <colding omesc com>
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  <colding omesc com>
+
+	* 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  <kmaraas gnome org>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]