Bug#582711: PATCH: IPv6 support for dico client
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
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
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
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
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