Bug#582711: PATCH: IPv6 support for dico client

2014-09-19 Thread أحمد المحمودي
On Fri, Sep 19, 2014 at 08:00:43PM +0300, أحمد المحمودي wrote:
   Anyways, I made better patch for dico client.
 
   Also, I've patched dicod server to listen on IPv6 addresses, what's 
   left is adding IPv6 support to the ACL.
---end quoted text---

  Forgot to attach patches in previous email !

-- 
 ‎أحمد المحمودي (Ahmed El-Mahmoudy)
  Digital design engineer
 GPG KeyID: 0xEDDDA1B7
 GPG Fingerprint: 8206 A196 2084 7E6D 0DF8  B176 BC19 6A94 EDDD A1B7
diff --git a/dico/cmdline.opt b/dico/cmdline.opt
index 3bd2cb3..8d4eb20 100644
--- a/dico/cmdline.opt
+++ b/dico/cmdline.opt
@@ -51,7 +51,7 @@ END
 OPTION(source,,ADDR,
[Set a source address for TCP connections.])
 BEGIN
-  source_addr = get_ipaddr(optarg);
+  source_addr = optarg;
   if (source_addr == 0)
 dico_die(1, 0, L_ERR, _(%s: Invalid IP or unknown host name),
  optarg);
diff --git a/dico/connect.c b/dico/connect.c
index 738b28f..dfcdfb1 100644
--- a/dico/connect.c
+++ b/dico/connect.c
@@ -272,44 +272,57 @@ dict_transcript(struct dict_connection *conn, int state)
 int
 dict_connect(struct dict_connection **pconn, dico_url_t url)
 {
-struct sockaddr_in s;
+struct addrinfo hints, *s;
+char urlport[6];
 int fd;
-IPADDR ip;
 dico_stream_t str;
 struct dict_connection *conn;
 
 XDICO_DEBUG_F2(1, _(Connecting to %s:%d\n), url-host,
 		   url-port ? url-port : DICO_DICT_PORT);
-fd = socket(PF_INET, SOCK_STREAM, 0);
-if (fd == -1) {
-	dico_log(L_ERR, errno,
-		 _(cannot create dict socket));
-	return 1;
-}
 
-s.sin_family = AF_INET;
-s.sin_addr.s_addr = htonl(source_addr);
-s.sin_port = 0;
-if (bind(fd, (struct sockaddr*) s, sizeof(s))  0) {
-	dico_log(L_ERR, errno,
-		 _(cannot bind AUTH socket));
+memset(hints, 0, sizeof hints);
+hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever, TODO: user configurable?
+hints.ai_socktype = SOCK_STREAM;
+
+if(source_addr != NULL) {
+  getaddrinfo(source_addr, 0, hints, s);
+  fd = socket(s-ai_family, s-ai_socktype, s-ai_protocol);
+  if (fd == -1) {
+		dico_log(L_ERR, errno,
+			 _(cannot create dict socket));
+		return 1;
+  }
+  if (bind(fd, s-ai_addr, s-ai_addrlen)  0) {
+		dico_log(L_ERR, errno,
+			 _(cannot bind AUTH socket));
+  }
+  freeaddrinfo(s);
 }
 
-ip = get_ipaddr(url-host);
-if (ip == 0) {
+sprintf(urlport, %d, (url-port ? url-port : DICO_DICT_PORT));
+
+if (getaddrinfo(url-host, urlport, hints, s) != 0) {
 	dico_log(L_ERR, 0, _(%s: Invalid IP or unknown host name),
 		 url-host);
 	return 1;
 }
-s.sin_addr.s_addr = htonl(ip);
-s.sin_port = htons(url-port ? url-port : DICO_DICT_PORT);
-if (connect(fd, (struct sockaddr*) s, sizeof(s)) == -1) {
+if(source_addr == NULL) {
+  fd = socket(s-ai_family, s-ai_socktype, s-ai_protocol);
+  if (fd == -1) {
+		dico_log(L_ERR, errno,
+			 _(cannot create dict socket));
+		return 1;
+  }
+}
+if (connect(fd,  s-ai_addr, s-ai_addrlen) == -1) {
 	dico_log(L_ERR, errno,
 		 _(cannot connect to DICT server %s:%d),
 		 url-host, url-port ? url-port : DICO_DICT_PORT);
 	close(fd);
 	return 1;
 }
+freeaddrinfo(s);
 
 if ((str = dico_fd_io_stream_create(fd, fd)) == NULL) {
 	dico_log(L_ERR, errno,
diff --git a/dico/dico-priv.h b/dico/dico-priv.h
index 046ad3f..8c711aa 100644
--- a/dico/dico-priv.h
+++ b/dico/dico-priv.h
@@ -140,7 +140,7 @@ extern struct auth_cred default_cred;
 extern char *client;
 extern enum dico_client_mode mode;
 extern int transcript;
-extern IPADDR source_addr;
+extern char *source_addr;
 extern int noauth_option;
 extern unsigned levenshtein_threshold;
 extern char *autologin_file;
diff --git a/dico/dico.c b/dico/dico.c
index 86491ce..4e9fd77 100644
--- a/dico/dico.c
+++ b/dico/dico.c
@@ -21,7 +21,7 @@ struct auth_cred default_cred;
 char *client = DICO_CLIENT_ID;
 enum dico_client_mode mode = mode_define;
 int transcript;
-IPADDR source_addr = INADDR_ANY;
+char *source_addr = NULL;
 int noauth_option;
 unsigned levenshtein_threshold;
 char *autologin_file;
diff --git a/dicod/accesslog.c b/dicod/accesslog.c
index 09991a0..4bd2af5 100644
--- a/dicod/accesslog.c
+++ b/dicod/accesslog.c
@@ -18,6 +18,10 @@
 #include fprintftime.h
 #include xgethostname.h
 
+#ifndef   NI_MAXHOST
+#define   NI_MAXHOST 1025
+#endif
+
 static char status[2][4];
 
 void
@@ -130,60 +134,19 @@ alog_print(FILE *fp, struct alog_instr *instr, int argc, char **argv)
 static char *
 sockaddr_to_hostname(struct sockaddr *sa, int resolve)
 {
-struct sockaddr_in *s_in;
-char *ret;
+char ret[NI_MAXHOST];
 
-switch (sa-sa_family) {
-case AF_INET:
-	s_in = (struct sockaddr_in*)sa;
-	if (resolve) {
-	struct hostent *hp;
-	hp = gethostbyaddr((char*) s_in-sin_addr,
-			   sizeof(s_in-sin_addr),
-			   AF_INET);
-	if (hp)
-		return xstrdup(hp-h_name);
-	}
-	ret = xstrdup(inet_ntoa(s_in-sin_addr));
-	break;
-	
-case AF_UNIX:
-	ret = 

Bug#582711: PATCH: IPv6 support for dico client

2014-09-19 Thread أحمد المحمودي
On Thu, Sep 18, 2014 at 03:26:03PM +0200, Marc Dequènes (Duck) wrote:
 As i see in /etc/hosts, localhost can either be 127.0.0.1 or ::1 because of
 this line (from a standard Debian install):
   ::1 localhost ip6-localhost ip6-loopback
 Which means it may have tried IPv6 first.
---end quoted text---

  Oh yes, indeed. You are right.

  Anyways, I made better patch for dico client.

  Also, I've patched dicod server to listen on IPv6 addresses, what's 
  left is adding IPv6 support to the ACL.

-- 
 ‎أحمد المحمودي (Ahmed El-Mahmoudy)
  Digital design engineer
 GPG KeyID: 0xEDDDA1B7
 GPG Fingerprint: 8206 A196 2084 7E6D 0DF8  B176 BC19 6A94 EDDD A1B7


signature.asc
Description: Digital signature


Bug#582711: PATCH: IPv6 support for dico client

2014-09-18 Thread أحمد المحمودي
Hello,

  I made a patch for dico client so that it can query dict servers that 
  have IPv6 addresses.

  It works, yet with an issue: if I set the --host argument to one of 
  localhost, ip6-localhost or ip6-loopback, I get the following 
  error message:

dico: Error: cannot connect to DICT server localhost:2628: Connection refused

  Yet setting --host=127.0.0.1 works just fine !

  I have attached the patch.

-- 
 ‎أحمد المحمودي (Ahmed El-Mahmoudy)
  Digital design engineer
 GPG KeyID: 0xEDDDA1B7
 GPG Fingerprint: 8206 A196 2084 7E6D 0DF8  B176 BC19 6A94 EDDD A1B7
diff --git a/dico/cmdline.opt b/dico/cmdline.opt
index 3bd2cb3..8d4eb20 100644
--- a/dico/cmdline.opt
+++ b/dico/cmdline.opt
@@ -51,7 +51,7 @@ END
 OPTION(source,,ADDR,
[Set a source address for TCP connections.])
 BEGIN
-  source_addr = get_ipaddr(optarg);
+  source_addr = optarg;
   if (source_addr == 0)
 dico_die(1, 0, L_ERR, _(%s: Invalid IP or unknown host name),
  optarg);
diff --git a/dico/connect.c b/dico/connect.c
index 738b28f..8ea6bd4 100644
--- a/dico/connect.c
+++ b/dico/connect.c
@@ -272,38 +272,50 @@ dict_transcript(struct dict_connection *conn, int state)
 int
 dict_connect(struct dict_connection **pconn, dico_url_t url)
 {
-struct sockaddr_in s;
+struct addrinfo hints, *s;
+char urlport[6];
 int fd;
-IPADDR ip;
 dico_stream_t str;
 struct dict_connection *conn;
 
 XDICO_DEBUG_F2(1, _(Connecting to %s:%d\n), url-host,
 		   url-port ? url-port : DICO_DICT_PORT);
-fd = socket(PF_INET, SOCK_STREAM, 0);
-if (fd == -1) {
-	dico_log(L_ERR, errno,
-		 _(cannot create dict socket));
-	return 1;
-}
 
-s.sin_family = AF_INET;
-s.sin_addr.s_addr = htonl(source_addr);
-s.sin_port = 0;
-if (bind(fd, (struct sockaddr*) s, sizeof(s))  0) {
-	dico_log(L_ERR, errno,
-		 _(cannot bind AUTH socket));
+memset(hints, 0, sizeof hints);
+hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever, TODO: user configurable?
+hints.ai_socktype = SOCK_STREAM;
+//hints.ai_flags = AI_PASSIVE; // fill in my IP for me
+
+if(source_addr != NULL) {
+  getaddrinfo(source_addr, 0, hints, s);
+  fd = socket(s-ai_family, s-ai_socktype, s-ai_protocol);
+  if (fd == -1) {
+		dico_log(L_ERR, errno,
+			 _(cannot create dict socket));
+		return 1;
+  }
+  if (bind(fd, s-ai_addr, s-ai_addrlen)  0) {
+		dico_log(L_ERR, errno,
+			 _(cannot bind AUTH socket));
+  }
 }
 
-ip = get_ipaddr(url-host);
-if (ip == 0) {
+sprintf(urlport, %d, (url-port ? url-port : DICO_DICT_PORT));
+
+if (getaddrinfo(url-host, urlport, hints, s) != 0) {
 	dico_log(L_ERR, 0, _(%s: Invalid IP or unknown host name),
 		 url-host);
 	return 1;
 }
-s.sin_addr.s_addr = htonl(ip);
-s.sin_port = htons(url-port ? url-port : DICO_DICT_PORT);
-if (connect(fd, (struct sockaddr*) s, sizeof(s)) == -1) {
+if(source_addr == NULL) {
+  fd = socket(s-ai_family, s-ai_socktype, s-ai_protocol);
+  if (fd == -1) {
+		dico_log(L_ERR, errno,
+			 _(cannot create dict socket));
+		return 1;
+  }
+}
+if (connect(fd,  s-ai_addr, s-ai_addrlen) == -1) {
 	dico_log(L_ERR, errno,
 		 _(cannot connect to DICT server %s:%d),
 		 url-host, url-port ? url-port : DICO_DICT_PORT);
diff --git a/dico/dico-priv.h b/dico/dico-priv.h
index 046ad3f..8c711aa 100644
--- a/dico/dico-priv.h
+++ b/dico/dico-priv.h
@@ -140,7 +140,7 @@ extern struct auth_cred default_cred;
 extern char *client;
 extern enum dico_client_mode mode;
 extern int transcript;
-extern IPADDR source_addr;
+extern char *source_addr;
 extern int noauth_option;
 extern unsigned levenshtein_threshold;
 extern char *autologin_file;
diff --git a/dico/dico.c b/dico/dico.c
index 86491ce..4e9fd77 100644
--- a/dico/dico.c
+++ b/dico/dico.c
@@ -21,7 +21,7 @@ struct auth_cred default_cred;
 char *client = DICO_CLIENT_ID;
 enum dico_client_mode mode = mode_define;
 int transcript;
-IPADDR source_addr = INADDR_ANY;
+char *source_addr = NULL;
 int noauth_option;
 unsigned levenshtein_threshold;
 char *autologin_file;


signature.asc
Description: Digital signature


Bug#582711: PATCH: IPv6 support for dico client

2014-09-18 Thread أحمد المحمودي
On Thu, Sep 18, 2014 at 11:44:26AM +0300, أحمد المحمودي wrote:
   It works, yet with an issue: if I set the --host argument to one of 
   localhost, ip6-localhost or ip6-loopback, I get the following 
   error message:
---end quoted text---

  I just found out that this problem happens only if I run dicod in 
  daemon mode. But if run in inetd mode, then
  dico --host=localhost lookup word runs successfully.

-- 
 ‎أحمد المحمودي (Ahmed El-Mahmoudy)
  Digital design engineer
 GPG KeyID: 0xEDDDA1B7
 GPG Fingerprint: 8206 A196 2084 7E6D 0DF8  B176 BC19 6A94 EDDD A1B7


signature.asc
Description: Digital signature


Bug#582711: PATCH: IPv6 support for dico client

2014-09-18 Thread Marc Dequènes (Duck)

Coin,

Quoting أحمد المحمودي aelmahmo...@users.sourceforge.net:


  I just found out that this problem happens only if I run dicod in
  daemon mode. But if run in inetd mode, then
  dico --host=localhost lookup word runs successfully.


As i see in /etc/hosts, localhost can either be 127.0.0.1 or ::1  
because of this line (from a standard Debian install):

  ::1 localhost ip6-localhost ip6-loopback
Which means it may have tried IPv6 first.

Also beware localhost.yourdomain may also be available in your DNS and…

I've not yet tested your patch but i think there is probably no  
specific problem with localhost.


Regards.

--
Marc Dequènes (Duck)


pgp_49nCbtEHZ.pgp
Description: PGP Digital Signature