summaryrefslogtreecommitdiffstats
path: root/rpc/rpc-transport/rdma/src/name.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpc/rpc-transport/rdma/src/name.c')
-rw-r--r--rpc/rpc-transport/rdma/src/name.c263
1 files changed, 127 insertions, 136 deletions
diff --git a/rpc/rpc-transport/rdma/src/name.c b/rpc/rpc-transport/rdma/src/name.c
index ae5c5d356..c57428ad6 100644
--- a/rpc/rpc-transport/rdma/src/name.c
+++ b/rpc/rpc-transport/rdma/src/name.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <sys/types.h>
@@ -22,12 +13,7 @@
#include <errno.h>
#include <netdb.h>
#include <string.h>
-
-#ifdef CLIENT_PORT_CEILING
-#undef CLIENT_PORT_CEILING
-#endif
-
-#define CLIENT_PORT_CEILING 1024
+#include <rdma/rdma_cma.h>
#ifndef AF_INET_SDP
#define AF_INET_SDP 27
@@ -35,37 +21,54 @@
#include "rpc-transport.h"
#include "rdma.h"
+#include "common-utils.h"
+
int32_t
-gf_resolve_ip6 (const char *hostname,
- uint16_t port,
- int family,
- void **dnscache,
+gf_resolve_ip6 (const char *hostname,
+ uint16_t port,
+ int family,
+ void **dnscache,
struct addrinfo **addr_info);
static int32_t
-af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr,
+af_inet_bind_to_port_lt_ceiling (struct rdma_cm_id *cm_id,
+ struct sockaddr *sockaddr,
socklen_t sockaddr_len, int ceiling)
{
- int32_t ret = -1;
- /* struct sockaddr_in sin = {0, }; */
- uint16_t port = ceiling - 1;
+ int32_t ret = -1;
+ uint16_t port = ceiling - 1;
+ // by default assume none of the ports are blocked and all are available
+ gf_boolean_t ports[1024] = {_gf_false,};
+ int i = 0;
+
+ ret = gf_process_reserved_ports (ports);
+ if (ret != 0) {
+ for (i = 0; i < 1024; i++)
+ ports[i] = _gf_false;
+ }
while (port)
{
switch (sockaddr->sa_family)
{
case AF_INET6:
- ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port);
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port
+ = htons (port);
break;
case AF_INET_SDP:
case AF_INET:
- ((struct sockaddr_in *)sockaddr)->sin_port = htons (port);
+ ((struct sockaddr_in *)sockaddr)->sin_port
+ = htons (port);
break;
}
-
- ret = bind (fd, sockaddr, sockaddr_len);
+ // ignore the reserved ports
+ if (ports[port] == _gf_true) {
+ port--;
+ continue;
+ }
+ ret = rdma_bind_addr (cm_id, sockaddr);
if (ret == 0)
break;
@@ -79,23 +82,22 @@ af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr,
return ret;
}
+#if 0
static int32_t
-af_unix_client_bind (rpc_transport_t *this,
- struct sockaddr *sockaddr,
- socklen_t sockaddr_len,
- int sock)
+af_unix_client_bind (rpc_transport_t *this, struct sockaddr *sockaddr,
+ socklen_t sockaddr_len, struct rdma_cm_id *cm_id)
{
data_t *path_data = NULL;
struct sockaddr_un *addr = NULL;
int32_t ret = -1;
- path_data = dict_get (this->options,
+ path_data = dict_get (this->options,
"transport.rdma.bind-path");
if (path_data) {
char *path = data_to_str (path_data);
if (!path || strlen (path) > UNIX_PATH_MAX) {
gf_log (this->name, GF_LOG_DEBUG,
- "transport.rdma.bind-path not specfied "
+ "transport.rdma.bind-path not specified "
"for unix socket, letting connect to assign "
"default value");
goto err;
@@ -106,7 +108,7 @@ af_unix_client_bind (rpc_transport_t *this,
ret = bind (sock, (struct sockaddr *)addr, sockaddr_len);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
- "cannot bind to unix-domain socket %d (%s)",
+ "cannot bind to unix-domain socket %d (%s)",
sock, strerror (errno));
goto err;
}
@@ -115,30 +117,31 @@ af_unix_client_bind (rpc_transport_t *this,
err:
return ret;
}
+#endif
static int32_t
client_fill_address_family (rpc_transport_t *this, struct sockaddr *sockaddr)
{
data_t *address_family_data = NULL;
- address_family_data = dict_get (this->options,
+ address_family_data = dict_get (this->options,
"transport.address-family");
if (!address_family_data) {
data_t *remote_host_data = NULL, *connect_path_data = NULL;
remote_host_data = dict_get (this->options, "remote-host");
- connect_path_data = dict_get (this->options,
+ connect_path_data = dict_get (this->options,
"transport.rdma.connect-path");
- if (!(remote_host_data || connect_path_data) ||
+ if (!(remote_host_data || connect_path_data) ||
(remote_host_data && connect_path_data)) {
gf_log (this->name, GF_LOG_ERROR,
"address-family not specified and not able to "
"determine the same from other options "
- "(remote-host:%s and connect-path:%s)",
- data_to_str (remote_host_data),
+ "(remote-host:%s and connect-path:%s)",
+ data_to_str (remote_host_data),
data_to_str (connect_path_data));
return -1;
- }
+ }
if (remote_host_data) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -162,13 +165,11 @@ client_fill_address_family (rpc_transport_t *this, struct sockaddr *sockaddr)
sockaddr->sa_family = AF_INET6;
} else if (!strcasecmp (address_family, "inet-sdp")) {
sockaddr->sa_family = AF_INET_SDP;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- sockaddr->sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
- "unknown address-family (%s) specified",
+ "unknown address-family (%s) specified",
address_family);
+ sockaddr->sa_family = AF_UNSPEC;
return -1;
}
}
@@ -177,8 +178,8 @@ client_fill_address_family (rpc_transport_t *this, struct sockaddr *sockaddr)
}
static int32_t
-af_inet_client_get_remote_sockaddr (rpc_transport_t *this,
- struct sockaddr *sockaddr,
+af_inet_client_get_remote_sockaddr (rpc_transport_t *this,
+ struct sockaddr *sockaddr,
socklen_t *sockaddr_len,
int16_t remote_port)
{
@@ -193,7 +194,7 @@ af_inet_client_get_remote_sockaddr (rpc_transport_t *this,
if (remote_host_data == NULL)
{
gf_log (this->name, GF_LOG_ERROR,
- "option remote-host missing in volume %s",
+ "option remote-host missing in volume %s",
this->name);
ret = -1;
goto err;
@@ -203,7 +204,7 @@ af_inet_client_get_remote_sockaddr (rpc_transport_t *this,
if (remote_host == NULL)
{
gf_log (this->name, GF_LOG_ERROR,
- "option remote-host has data NULL in volume %s",
+ "option remote-host has data NULL in volume %s",
this->name);
ret = -1;
goto err;
@@ -238,7 +239,7 @@ af_inet_client_get_remote_sockaddr (rpc_transport_t *this,
/* TODO: gf_resolve is a blocking call. kick in some
non blocking dns techniques */
ret = gf_resolve_ip6 (remote_host, remote_port,
- sockaddr->sa_family,
+ sockaddr->sa_family,
&this->dnscache, &addr_info);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
@@ -254,8 +255,8 @@ err:
}
static int32_t
-af_unix_client_get_remote_sockaddr (rpc_transport_t *this,
- struct sockaddr *sockaddr,
+af_unix_client_get_remote_sockaddr (rpc_transport_t *this,
+ struct sockaddr *sockaddr,
socklen_t *sockaddr_len)
{
struct sockaddr_un *sockaddr_un = NULL;
@@ -263,7 +264,7 @@ af_unix_client_get_remote_sockaddr (rpc_transport_t *this,
data_t *connect_path_data = NULL;
int32_t ret = 0;
- connect_path_data = dict_get (this->options,
+ connect_path_data = dict_get (this->options,
"transport.rdma.connect-path");
if (!connect_path_data) {
gf_log (this->name, GF_LOG_ERROR,
@@ -311,7 +312,7 @@ af_unix_server_get_local_sockaddr (rpc_transport_t *this,
struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
- listen_path_data = dict_get (this->options,
+ listen_path_data = dict_get (this->options,
"transport.rdma.listen-path");
if (!listen_path_data) {
gf_log (this->name, GF_LOG_ERROR,
@@ -342,9 +343,9 @@ err:
return ret;
}
-static int32_t
-af_inet_server_get_local_sockaddr (rpc_transport_t *this,
- struct sockaddr *addr,
+static int32_t
+af_inet_server_get_local_sockaddr (rpc_transport_t *this,
+ struct sockaddr *addr,
socklen_t *addr_len)
{
struct addrinfo hints, *res = 0;
@@ -360,31 +361,31 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
listen_host_data = dict_get (options,
"transport.rdma.bind-address");
- if (listen_port_data)
- {
+ if (listen_port_data) {
listen_port = data_to_uint16 (listen_port_data);
} else {
- if (addr->sa_family == AF_INET6) {
- struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
- in->sin6_addr = in6addr_any;
- in->sin6_port = htons(listen_port);
- *addr_len = sizeof(struct sockaddr_in6);
+ listen_port = GF_DEFAULT_RDMA_LISTEN_PORT;
+
+ if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
+ in->sin6_addr = in6addr_any;
+ in->sin6_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in6);
goto out;
- } else if (addr->sa_family == AF_INET) {
- struct sockaddr_in *in = (struct sockaddr_in *) addr;
- in->sin_addr.s_addr = htonl(INADDR_ANY);
- in->sin_port = htons(listen_port);
- *addr_len = sizeof(struct sockaddr_in);
+ } else if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *in = (struct sockaddr_in *) addr;
+ in->sin_addr.s_addr = htonl(INADDR_ANY);
+ in->sin_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in);
goto out;
- }
- }
+ }
+ }
if (listen_port == (uint16_t) -1)
listen_port = GF_DEFAULT_RDMA_LISTEN_PORT;
- if (listen_host_data)
- {
+ if (listen_host_data) {
listen_host = data_to_str (listen_host_data);
}
@@ -398,9 +399,8 @@ af_inet_server_get_local_sockaddr (rpc_transport_t *this,
ret = getaddrinfo(listen_host, service, &hints, &res);
if (ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "getaddrinfo failed for host %s, service %s (%s)",
+ gf_log (this->name, GF_LOG_ERROR,
+ "getaddrinfo failed for host %s, service %s (%s)",
listen_host, service, gai_strerror (ret));
ret = -1;
goto out;
@@ -416,10 +416,8 @@ out:
}
int32_t
-gf_rdma_client_bind (rpc_transport_t *this,
- struct sockaddr *sockaddr,
- socklen_t *sockaddr_len,
- int sock)
+gf_rdma_client_bind (rpc_transport_t *this, struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len, struct rdma_cm_id *cm_id)
{
int ret = 0;
@@ -431,22 +429,24 @@ gf_rdma_client_bind (rpc_transport_t *this,
*sockaddr_len = sizeof (struct sockaddr_in);
case AF_INET6:
- ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
- *sockaddr_len,
- CLIENT_PORT_CEILING);
+ ret = af_inet_bind_to_port_lt_ceiling (cm_id, sockaddr,
+ *sockaddr_len,
+ GF_CLIENT_PORT_CEILING);
if (ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot bind inet socket (%d) to port "
- "less than %d (%s)",
- sock, CLIENT_PORT_CEILING, strerror (errno));
+ "cannot bind rdma_cm_id to port "
+ "less than %d (%s)", GF_CLIENT_PORT_CEILING,
+ strerror (errno));
ret = 0;
}
break;
case AF_UNIX:
*sockaddr_len = sizeof (struct sockaddr_un);
- ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr,
+#if 0
+ ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr,
*sockaddr_len, sock);
+#endif
break;
default:
@@ -473,7 +473,7 @@ gf_rdma_client_get_remote_sockaddr (rpc_transport_t *this,
ret = -1;
goto err;
}
-
+
switch (sockaddr->sa_family)
{
case AF_INET_SDP:
@@ -483,7 +483,7 @@ gf_rdma_client_get_remote_sockaddr (rpc_transport_t *this,
case AF_INET:
case AF_INET6:
case AF_UNSPEC:
- ret = af_inet_client_get_remote_sockaddr (this,
+ ret = af_inet_client_get_remote_sockaddr (this,
sockaddr,
sockaddr_len,
remote_port);
@@ -495,8 +495,8 @@ gf_rdma_client_get_remote_sockaddr (rpc_transport_t *this,
break;
case AF_UNIX:
- ret = af_unix_client_get_remote_sockaddr (this,
- sockaddr,
+ ret = af_unix_client_get_remote_sockaddr (this,
+ sockaddr,
sockaddr_len);
break;
@@ -505,21 +505,21 @@ gf_rdma_client_get_remote_sockaddr (rpc_transport_t *this,
"unknown address-family %d", sockaddr->sa_family);
ret = -1;
}
-
+
err:
return ret;
}
int32_t
gf_rdma_server_get_local_sockaddr (rpc_transport_t *this,
- struct sockaddr *addr,
- socklen_t *addr_len)
+ struct sockaddr *addr,
+ socklen_t *addr_len)
{
data_t *address_family_data = NULL;
int32_t ret = 0;
char is_inet_sdp = 0;
- address_family_data = dict_get (this->options,
+ address_family_data = dict_get (this->options,
"transport.address-family");
if (address_family_data) {
char *address_family = NULL;
@@ -533,21 +533,19 @@ gf_rdma_server_get_local_sockaddr (rpc_transport_t *this,
addr->sa_family = AF_INET_SDP;
} else if (!strcasecmp (address_family, "unix")) {
addr->sa_family = AF_UNIX;
- } else if (!strcasecmp (address_family, "inet/inet6")
- || !strcasecmp (address_family, "inet6/inet")) {
- addr->sa_family = AF_UNSPEC;
} else {
gf_log (this->name, GF_LOG_ERROR,
- "unknown address family (%s) specified",
+ "unknown address family (%s) specified",
address_family);
+ addr->sa_family = AF_UNSPEC;
ret = -1;
goto err;
}
} else {
gf_log (this->name, GF_LOG_DEBUG,
"option address-family not specified, defaulting "
- "to inet/inet6");
- addr->sa_family = AF_UNSPEC;
+ "to inet");
+ addr->sa_family = AF_INET;
}
switch (addr->sa_family)
@@ -574,60 +572,53 @@ err:
return ret;
}
-int32_t
-fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *addr,
+int32_t
+fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *addr,
int32_t addr_len, char *identifier)
{
int32_t ret = 0, tmpaddr_len = 0;
char service[NI_MAXSERV], host[NI_MAXHOST];
- struct sockaddr_storage tmpaddr;
+ union gf_sock_union sock_union;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
- tmpaddr = *addr;
+ memset (&sock_union, 0, sizeof (sock_union));
+ sock_union.storage = *addr;
tmpaddr_len = addr_len;
- if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) {
+ if (sock_union.sa.sa_family == AF_INET6) {
int32_t one_to_four, four_to_eight, twelve_to_sixteen;
int16_t eight_to_ten, ten_to_twelve;
-
+
one_to_four = four_to_eight = twelve_to_sixteen = 0;
eight_to_ten = ten_to_twelve = 0;
-
- one_to_four = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[0];
- four_to_eight = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[1];
+
+ one_to_four = sock_union.sin6.sin6_addr.s6_addr32[0];
+ four_to_eight = sock_union.sin6.sin6_addr.s6_addr32[1];
#ifdef GF_SOLARIS_HOST_OS
- eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr)[4];
+ eight_to_ten = S6_ADDR16(sock_union.sin6.sin6_addr)[4];
#else
- eight_to_ten = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr16[4];
+ eight_to_ten = sock_union.sin6.sin6_addr.s6_addr16[4];
#endif
#ifdef GF_SOLARIS_HOST_OS
- ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr)[5];
+ ten_to_twelve = S6_ADDR16(sock_union.sin6.sin6_addr)[5];
#else
- ten_to_twelve = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr16[5];
+ ten_to_twelve = sock_union.sin6.sin6_addr.s6_addr16[5];
#endif
- twelve_to_sixteen = ((struct sockaddr_in6 *)
- &tmpaddr)->sin6_addr.s6_addr32[3];
+ twelve_to_sixteen = sock_union.sin6.sin6_addr.s6_addr32[3];
/* ipv4 mapped ipv6 address has
bits 0-80: 0
bits 80-96: 0xffff
- bits 96-128: ipv4 address
+ bits 96-128: ipv4 address
*/
-
+
if (one_to_four == 0 &&
four_to_eight == 0 &&
eight_to_ten == 0 &&
ten_to_twelve == -1) {
- struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr;
- memset (&tmpaddr, 0, sizeof (tmpaddr));
-
+ struct sockaddr_in *in_ptr = &sock_union.sin;
+ memset (&sock_union, 0, sizeof (sock_union));
+
in_ptr->sin_family = AF_INET;
in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port;
in_ptr->sin_addr.s_addr = twelve_to_sixteen;
@@ -635,7 +626,7 @@ fill_inet6_inet_identifiers (rpc_transport_t *this, struct sockaddr_storage *add
}
}
- ret = getnameinfo ((struct sockaddr *) &tmpaddr,
+ ret = getnameinfo (&sock_union.sa,
tmpaddr_len,
host, sizeof (host),
service, sizeof (service),
@@ -666,8 +657,8 @@ gf_rdma_get_transport_identifiers (rpc_transport_t *this)
case AF_INET:
case AF_INET6:
{
- ret = fill_inet6_inet_identifiers (this,
- &this->myinfo.sockaddr,
+ ret = fill_inet6_inet_identifiers (this,
+ &this->myinfo.sockaddr,
this->myinfo.sockaddr_len,
this->myinfo.identifier);
if (ret == -1) {
@@ -705,7 +696,7 @@ gf_rdma_get_transport_identifiers (rpc_transport_t *this)
break;
default:
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_ERROR,
"unknown address family (%d)",
((struct sockaddr *) &this->myinfo.sockaddr)->sa_family);
ret = -1;