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

[Nbd] Specifying interface to listen on



Hi,

nbd-server lacks ability to specify the IP address to listen on. For
example, I have a server with a public IP and a private one (on a LAN).
I would like nbd-server to serve only on a private network. Attached
patch adds this functionality.

bye,
Filip Zyzniewski
Tefnet
--- nbd-2.9.7-orig/nbd-server.c	2007-09-27 10:06:41.000000000 +0200
+++ nbd-2.9.7/nbd-server.c	2007-09-27 12:05:04.000000000 +0200
@@ -171,6 +171,7 @@
 	gchar* exportname;    /**< (unprocessed) filename of the file we're exporting */
 	off_t expected_size; /**< size of the exported file as it was told to
 			       us through configuration */
+	gchar *host;		/**< host we're listening on */
 	unsigned int port;   /**< port we're exporting this file at */
 	char* authname;      /**< filename of the authorization file */
 	int flags;           /**< flags associated with this exported file */
@@ -333,7 +334,7 @@
  */
 void usage() {
 	printf("This is nbd-server version " VERSION "\n");
-	printf("Usage: port file_to_export [size][kKmM] [-l authorize_file] [-r] [-m] [-c] [-x program] [-X program] [-a timeout_sec] [-C configuration file] [-p PID file name] [-o section name]\n"
+	printf("Usage: [host:]port file_to_export [size][kKmM] [-l authorize_file] [-r] [-m] [-c] [-x program] [-X program] [-a timeout_sec] [-C configuration file] [-p PID file name] [-o section name]\n"
 	       "\t-r|--read-only\t\tread only\n"
 	       "\t-m|--multi-file\t\tmultiple file\n"
 	       "\t-c|--copy-on-write\tcopy on write\n"
@@ -354,6 +355,7 @@
 void dump_section(SERVER* serve, gchar* section_header) {
 	printf("[%s]\n", section_header);
 	printf("\texportname = %s\n", serve->exportname);
+	printf("\thost = %d\n", serve->host);
 	printf("\tport = %d\n", serve->port);
 	if(serve->flags & F_READONLY) {
 		printf("\treadonly = true\n");
@@ -409,6 +411,7 @@
 	off_t es;
 	size_t last;
 	char suffix;
+	char *colon;
 	gboolean do_output=FALSE;
 	gchar* section_header;
 
@@ -424,6 +427,14 @@
 			/* non-option argument */
 			switch(nonspecial++) {
 			case 0:
+				colon=strchr(optarg, ':');
+				if(colon) {
+					*colon='\0';
+					serve->host = g_strdup(optarg);
+					optarg=colon+1;
+				} else {
+					serve->host = g_strdup("0.0.0.0");
+				}
 				serve->port=strtol(optarg, NULL, 0);
 				break;
 			case 1:
@@ -547,6 +558,7 @@
 	gchar *virtstyle=NULL;
 	PARAM lp[] = {
 		{ "exportname", TRUE,	PARAM_STRING, 	NULL, 0 },
+		{ "host", 	TRUE,	PARAM_STRING, 	NULL, 0 },
 		{ "port", 	TRUE,	PARAM_INT, 	NULL, 0 },
 		{ "authfile",	FALSE,	PARAM_STRING,	NULL, 0 },
 		{ "timeout",	FALSE,	PARAM_INT,	NULL, 0 },
@@ -560,7 +572,7 @@
 		{ "autoreadonly", FALSE, PARAM_BOOL,	NULL, F_AUTOREADONLY },
 		{ "sparse_cow",	FALSE,	PARAM_BOOL,	NULL, F_SPARSE },
 	};
-	const int lp_size=11;
+	const int lp_size=12;
 	PARAM gp[] = {
 		{ "user",	FALSE, PARAM_STRING,	&runuser,	0 },
 		{ "group",	FALSE, PARAM_STRING,	&rungroup,	0 },
@@ -595,15 +607,16 @@
 	for(i=0;groups[i];i++) {
 		memset(&s, '\0', sizeof(SERVER));
 		lp[0].target=&(s.exportname);
-		lp[1].target=&(s.port);
-		lp[2].target=&(s.authname);
-		lp[3].target=&(s.timeout);
-		lp[4].target=&(s.expected_size);
-		lp[5].target=&(virtstyle);
-		lp[6].target=&(s.prerun);
-		lp[7].target=&(s.postrun);
-		lp[8].target=lp[9].target=lp[10].target=
-				lp[11].target=lp[12].target=&(s.flags);
+		lp[1].target=&(s.host);
+		lp[2].target=&(s.port);
+		lp[3].target=&(s.authname);
+		lp[4].target=&(s.timeout);
+		lp[5].target=&(s.expected_size);
+		lp[6].target=&(virtstyle);
+		lp[7].target=&(s.prerun);
+		lp[8].target=&(s.postrun);
+		lp[9].target=lp[10].target=lp[11].target=
+				lp[12].target=lp[13].target=&(s.flags);
 		
 		/* After the [generic] group, start parsing exports */
 		if(i==1) {
@@ -1413,6 +1426,7 @@
  **/
 void setup_serve(SERVER *serve) {
 	struct sockaddr_in addrin;
+	struct hostent *hen;
 	struct sigaction sa;
 	int addrinlen = sizeof(addrin);
 	int sock_flags;
@@ -1443,7 +1457,12 @@
 	DEBUG("Waiting for connections... bind, ");
 	addrin.sin_family = AF_INET;
 	addrin.sin_port = htons(serve->port);
-	addrin.sin_addr.s_addr = 0;
+
+	hen=gethostbyname(serve->host);
+	if(!hen)
+		err("could not resolve server name: %h");
+	memcpy(&(addrin.sin_addr.s_addr), hen->h_addr_list[0], hen->h_length);
+
 	if (bind(serve->socket, (struct sockaddr *) &addrin, addrinlen) < 0)
 		err("bind: %m");
 	DEBUG("listen, ");

Reply to: