From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lon Hohberger Date: Wed, 29 Sep 2010 11:25:51 -0400 Subject: [Cluster-devel] [PATCH] Fix ipv6 support in ccs_sync Message-ID: <1285773951-19979-1-git-send-email-lhh@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Signed-off-by: Lon Hohberger --- ricci/ccs_sync/Makefile | 2 +- ricci/ccs_sync/ricci_conf.c | 54 +++++++++++++++++++++++++++++++++++------- ricci/ccs_sync/ricci_net.h | 1 + ricci/ccs_sync/ricci_nss.c | 29 +++++++++++++++++++++- ricci/ccs_sync/ricci_nss.h | 9 ++++-- 5 files changed, 80 insertions(+), 15 deletions(-) diff --git a/ricci/ccs_sync/Makefile b/ricci/ccs_sync/Makefile index 06adc34..382969e 100644 --- a/ricci/ccs_sync/Makefile +++ b/ricci/ccs_sync/Makefile @@ -25,7 +25,7 @@ OBJECTS = \ CC=gcc INCLUDE = -I/usr/include/libxml2 -I/usr/include/nspr4 `nss-config --cflags` CFLAGS = -O2 -Wall -Wextra -Wformat=2 -fstack-protector -Wshadow $(INCLUDE) -LDFLAGS = -lxml2 `nss-config --libs` +LDFLAGS = -lxml2 `nss-config --libs` `nspr-config --libs` all: ${TARGET} diff --git a/ricci/ccs_sync/ricci_conf.c b/ricci/ccs_sync/ricci_conf.c index 84c9bc9..f523022 100644 --- a/ricci/ccs_sync/ricci_conf.c +++ b/ricci/ccs_sync/ricci_conf.c @@ -266,11 +266,36 @@ static int ricci_conn_cmp(void *l, void *r) { return (-1); } +int get_addr_info(const char *name, PRUint16 port, PRNetAddr *addr_out) +{ + PRAddrInfo *pr_ai = NULL; + void *e = NULL; + PRNetAddr addr; + int ret = -1; + + pr_ai = PR_GetAddrInfoByName(name, PR_AF_UNSPEC, PR_AI_ADDRCONFIG); + if (!pr_ai) + return -1; + + ret = 1; + e = PR_EnumerateAddrInfo(0, pr_ai, port, &addr); + if (e) + ret = 0; + + if (addr_out) + memcpy(addr_out, &addr, sizeof(*addr_out)); + + PR_FreeAddrInfo(pr_ai); + + return ret; +} + static int ricci_conn_alloc(void *data, void *param) { hash_t *conn_hash = (hash_t *) param; const char *name = (const char *) data; struct ricci_conn *c; PRStatus status; + PRNetAddr addr; if (name == NULL || conn_hash == NULL) return (-1); @@ -279,23 +304,32 @@ static int ricci_conn_alloc(void *data, void *param) { if (c == NULL) goto oom0; - c->fd = get_ssl_socket(NULL, PR_TRUE); - if (c->fd == NULL) - goto oom1; - c->hostname = strdup(name); if (c->hostname == NULL) - goto oom2; + goto oom1; c->buf = malloc(DEFAULT_READBUF_LEN); if (c->buf == NULL) - goto oom3; + goto oom2; c->bufsize = DEFAULT_READBUF_LEN; c->port = ricci_port; time(&c->last_active); - status = nss_connect(c->fd, c->hostname, c->port); + if (get_addr_info(c->hostname, c->port, &addr) != 0) + goto oom2; + + c->pr_addr = calloc(1, sizeof(*c->pr_addr)); + if (!c->pr_addr) + goto oom2; + + memcpy(c->pr_addr, &addr, sizeof(*c->pr_addr)); + + c->fd = get_ssl_socket(NULL, PR_TRUE, c->pr_addr->raw.family); + if (c->fd == NULL) + goto oom3; + + status = nss_connect_by_addr(c->fd, c->hostname, c->pr_addr); if (status == PR_FAILURE) { fprintf(stderr, "Unable to connect to %s\n", c->hostname); ricci_conn_dtor(NULL, c); @@ -309,9 +343,11 @@ static int ricci_conn_alloc(void *data, void *param) { return (0); oom3: - free(c->hostname); -oom2: PR_Close(c->fd); +oom2: + free(c->pr_addr); + free(c->hostname); + free(c->buf); oom1: free(c); oom0: diff --git a/ricci/ccs_sync/ricci_net.h b/ricci/ccs_sync/ricci_net.h index 033baed..bd37087 100644 --- a/ricci/ccs_sync/ricci_net.h +++ b/ricci/ccs_sync/ricci_net.h @@ -26,6 +26,7 @@ enum { struct ricci_conn { PRFileDesc *fd; + PRNetAddr *pr_addr; char *hostname; char *cluster_name; char *buf; diff --git a/ricci/ccs_sync/ricci_nss.c b/ricci/ccs_sync/ricci_nss.c index 36f151d..65e2ac4 100644 --- a/ricci/ccs_sync/ricci_nss.c +++ b/ricci/ccs_sync/ricci_nss.c @@ -114,14 +114,14 @@ PRStatus set_nss_sockopt_nonblock(PRFileDesc *sock, PRBool val) { return (PR_SetSocketOption(sock, &sock_opt)); } -PRFileDesc *get_ssl_socket(const char *cert_nick, PRBool nonblocking) { +PRFileDesc *get_ssl_socket(const char *cert_nick, PRBool nonblocking, PRUint16 af) { PRFileDesc *tcp_sock; PRFileDesc *ssl_sock; PRSocketOptionData sock_opt; PRStatus pr_status; SECStatus sec_status; - tcp_sock = PR_NewTCPSocket(); + tcp_sock = PR_OpenTCPSocket(af); if (tcp_sock == NULL) return (NULL); @@ -176,6 +176,7 @@ PRFileDesc *get_ssl_socket(const char *cert_nick, PRBool nonblocking) { return (ssl_sock); } + PRStatus nss_connect(PRFileDesc *sock, const char *addr_str, uint16_t port) { char buf[PR_NETDB_BUF_SIZE]; PRStatus pr_status; @@ -209,6 +210,30 @@ PRStatus nss_connect(PRFileDesc *sock, const char *addr_str, uint16_t port) { return (PR_SUCCESS); } + +PRStatus nss_connect_by_addr(PRFileDesc *sock, const char *addr_str, + PRNetAddr *target) +{ + SECStatus sec_status; + PRStatus pr_status; + + sec_status = SSL_SetURL(sock, addr_str); + if (sec_status != SECSuccess) + return (PR_FAILURE); + + pr_status = PR_Connect(sock, target, PR_INTERVAL_NO_TIMEOUT); + if (pr_status != PR_SUCCESS) { + if (errno != EINPROGRESS) + return (pr_status); + } + + sec_status = SSL_ResetHandshake(sock, PR_FALSE); + if (sec_status != SECSuccess) + return (PR_FAILURE); + + return (PR_SUCCESS); +} + int init_libnss_ssl(const char *cert_db_dir) { SECStatus status; diff --git a/ricci/ccs_sync/ricci_nss.h b/ricci/ccs_sync/ricci_nss.h index 2b47d54..1bb9dd0 100644 --- a/ricci/ccs_sync/ricci_nss.h +++ b/ricci/ccs_sync/ricci_nss.h @@ -12,10 +12,13 @@ #define __RICCI_NSS_H SECStatus nss_connect( PRFileDesc *ssl_sock, - const char *addr_str, - uint16_t port); + const char *addr_str, + uint16_t port); +SECStatus nss_connect_by_addr( PRFileDesc *ssl_sock, + const char *addr_str, + PRNetAddr *addr); -PRFileDesc *get_ssl_socket(const char *cert_nick, PRBool nonblocking); +PRFileDesc *get_ssl_socket(const char *cert_nick, PRBool nonblocking, PRUint16 af); int init_libnss_ssl(const char *cert_db_dir); int shutdown_libnss_ssl(void); PRStatus set_nss_sockopt_nonblock(PRFileDesc *sock, PRBool val); -- 1.7.2.2