From: Jeff Layton <jlayton@redhat.com>
To: linux-nfs@vger.kernel.org, nfsv4@linux-nfs.org
Cc: kwc@citi.umich.edu, chuck.lever@oracle.com
Subject: [PATCH 2/6] nfs-utils: store the address given in the upcall for later use
Date: Wed, 11 Mar 2009 12:42:58 -0400 [thread overview]
Message-ID: <1236789782-8867-3-git-send-email-jlayton@redhat.com> (raw)
In-Reply-To: <1236789782-8867-1-git-send-email-jlayton@redhat.com>
The current upcall is rather inefficient. We first convert the address
to a hostname, and then later when we set up the RPC client, we do a
hostname lookup to convert it back to an address.
Begin to change this by keeping the address in the clnt_info that we
get out of the upcall. Since a sockaddr has a port field, we can also
eliminate the port from the clnt_info.
Finally, switch to getnameinfo() instead of gethostbyaddr(). We'll
need to use that call anyway when we switch to using IPv6.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
utils/gssd/gssd.h | 2 +-
utils/gssd/gssd_proc.c | 105 ++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 90 insertions(+), 17 deletions(-)
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
index 082039a..20f52ff 100644
--- a/utils/gssd/gssd.h
+++ b/utils/gssd/gssd.h
@@ -83,7 +83,7 @@ struct clnt_info {
int krb5_poll_index;
int spkm3_fd;
int spkm3_poll_index;
- int port;
+ struct sockaddr_storage *addr;
};
void init_client_list(void);
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index 509946e..4f05040 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -102,10 +102,80 @@ struct pollfd * pollarray;
int pollsize; /* the size of pollaray (in pollfd's) */
+/*
+ * convert an address string to a sockaddr_storage struct
+ */
+static struct sockaddr_storage *
+addrstr_to_sockaddr(const char *addr, const int port)
+{
+ struct sockaddr_storage *ss;
+ struct sockaddr_in *s4;
+
+ ss = calloc(1, sizeof(struct sockaddr_storage));
+ if (!ss) {
+ printerr(0, "ERROR: unable to allocate storage to convert "
+ "address %s\n", addr);
+ goto out;
+ }
+
+ s4 = (struct sockaddr_in *) ss;
+
+ if (inet_pton(AF_INET, addr, &s4->sin_addr)) {
+ s4->sin_family = AF_INET;
+ s4->sin_port = htons(port);
+ } else {
+ printerr(0, "ERROR: unable to convert %s to address\n", addr);
+ free(ss);
+ ss = NULL;
+ }
+out:
+ return ss;
+}
+
+/*
+ * convert a sockaddr to a hostname
+ */
+static char *
+sockaddr_to_hostname(const struct sockaddr *sa, const char *addr)
+{
+#define MAX_HOSTNAME_LEN 127
+ char *hostname;
+ socklen_t addrlen;
+ int err;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+ default:
+ printerr(0, "ERROR: unrecognized addr family %d\n",
+ sa->sa_family);
+ return NULL;
+ }
+
+ hostname = calloc(1, MAX_HOSTNAME_LEN + 1);
+ if (!hostname) {
+ printerr(0, "ERROR: unable to allocate hostname string\n");
+ return NULL;
+ }
+
+ err = getnameinfo(sa, addrlen, hostname, MAX_HOSTNAME_LEN, NULL,
+ 0, NI_NAMEREQD);
+ if (err) {
+ free(hostname);
+ hostname = NULL;
+ printerr(0, "ERROR: unable to resolve %s to hostname: %s\n",
+ addr, gai_strerror(err));
+ }
+
+ return hostname;
+}
+
/* XXX buffer problems: */
static int
read_service_info(char *info_file_name, char **servicename, char **servername,
- int *prog, int *vers, char **protocol, int *port) {
+ int *prog, int *vers, char **protocol,
+ struct sockaddr_storage **addr) {
#define INFOBUFLEN 256
char buf[INFOBUFLEN + 1];
static char dummy[128];
@@ -117,12 +187,12 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
char protoname[16];
char cb_port[128];
char *p;
- in_addr_t inaddr;
int fd = -1;
- struct hostent *ent = NULL;
int numfields;
+ int port = 0;
*servicename = *servername = *protocol = NULL;
+ *addr = NULL;
if ((fd = open(info_file_name, O_RDONLY)) == -1) {
printerr(0, "ERROR: can't open %s: %s\n", info_file_name,
@@ -160,21 +230,20 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
if((*prog != 100003) || ((*vers != 2) && (*vers != 3) && (*vers != 4)))
goto fail;
- /* create service name */
- inaddr = inet_addr(address);
- if (!(ent = gethostbyaddr(&inaddr, sizeof(inaddr), AF_INET))) {
- printerr(0, "ERROR: can't resolve server %s name\n", address);
+ if (cb_port[0] != '\0')
+ port = atoi(cb_port);
+ *addr = addrstr_to_sockaddr(address, port);
+ if (*addr == NULL)
goto fail;
- }
- if (!(*servername = calloc(strlen(ent->h_name) + 1, 1)))
+
+ *servername = sockaddr_to_hostname((struct sockaddr *) *addr, address);
+ if (*servername == NULL)
goto fail;
- memcpy(*servername, ent->h_name, strlen(ent->h_name));
- snprintf(buf, INFOBUFLEN, "%s@%s", service, ent->h_name);
+
+ snprintf(buf, INFOBUFLEN, "%s@%s", service, *servername);
if (!(*servicename = calloc(strlen(buf) + 1, 1)))
goto fail;
memcpy(*servicename, buf, strlen(buf));
- if (cb_port[0] != '\0')
- *port = atoi(cb_port);
if (!(*protocol = strdup(protoname)))
goto fail;
@@ -185,7 +254,9 @@ fail:
free(*servername);
free(*servicename);
free(*protocol);
+ free(*addr);
*servicename = *servername = *protocol = NULL;
+ *addr = NULL;
return -1;
}
@@ -205,6 +276,7 @@ destroy_client(struct clnt_info *clp)
free(clp->servicename);
free(clp->servername);
free(clp->protocol);
+ free(clp->addr);
free(clp);
}
@@ -251,7 +323,7 @@ process_clnt_dir_files(struct clnt_info * clp)
if ((clp->servicename == NULL) &&
read_service_info(info_file_name, &clp->servicename,
&clp->servername, &clp->prog, &clp->vers,
- &clp->protocol, &clp->port))
+ &clp->protocol, &clp->addr))
return -1;
return 0;
}
@@ -599,8 +671,9 @@ int create_auth_rpc_client(struct clnt_info *clp,
clp->servername, uid);
goto out_fail;
}
- if (clp->port)
- ((struct sockaddr_in *)a->ai_addr)->sin_port = htons(clp->port);
+ if (((struct sockaddr_in *) clp->addr)->sin_port != 0)
+ ((struct sockaddr_in *) a->ai_addr)->sin_port =
+ ((struct sockaddr_in *) clp->addr)->sin_port;
if (a->ai_protocol == IPPROTO_TCP) {
if ((rpc_clnt = clnttcp_create(
(struct sockaddr_in *) a->ai_addr,
--
1.6.0.6
next prev parent reply other threads:[~2009-03-11 16:43 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-11 16:42 [PATCH 0/6] nfs-utils: convert gssd to TI-RPC and add IPv6 support (RFC) Jeff Layton
2009-03-11 16:42 ` [PATCH 1/6] nfs-utils: make getnameinfo() required for --enable-gss Jeff Layton
2009-03-11 16:42 ` Jeff Layton [this message]
2009-03-11 21:41 ` [PATCH 2/6] nfs-utils: store the address given in the upcall for later use Chuck Lever
2009-03-11 16:42 ` [PATCH 3/6] nfs-utils: skip getaddrinfo in create_auth_rpc_client unless we need port Jeff Layton
2009-03-11 22:09 ` Chuck Lever
2009-03-12 21:48 ` Jeff Layton
2009-03-11 16:43 ` [PATCH 4/6] nfs-utils: split out gssd rpc client creation into separate function Jeff Layton
2009-03-11 16:43 ` [PATCH 5/6] nfs-utils: when TIRPC is enabled, use new API to create RPC client Jeff Layton
2009-03-11 16:43 ` [PATCH 6/6] nfs-utils: add IPv6 code to gssd Jeff Layton
2009-04-01 14:23 [PATCH 0/6] nfs-utils: convert gssd to TI-RPC and add IPv6 support (try #2) Jeff Layton
2009-04-01 14:24 ` [PATCH 2/6] nfs-utils: store the address given in the upcall for later use Jeff Layton
2009-04-01 16:58 ` Chuck Lever
2009-04-01 17:06 ` Jeff Layton
2009-04-01 17:14 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1236789782-8867-3-git-send-email-jlayton@redhat.com \
--to=jlayton@redhat.com \
--cc=chuck.lever@oracle.com \
--cc=kwc@citi.umich.edu \
--cc=linux-nfs@vger.kernel.org \
--cc=nfsv4@linux-nfs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.