Skip to content

Instantly share code, notes, and snippets.

@joerns
Created March 14, 2016 11:25
Show Gist options
  • Save joerns/c9a25e9b9e1fab3ea92b to your computer and use it in GitHub Desktop.
Save joerns/c9a25e9b9e1fab3ea92b to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <rdma/fabric.h>
#include <rdma/fi_eq.h>
#include <rdma/fi_endpoint.h>
#include <rdma/fi_cm.h>
#include <rdma/fi_errno.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#define ERROR(x, ...) \
do { \
fprintf(stderr, "error: "x"\n", __VA_ARGS__);\
exit(EXIT_FAILURE);\
} while(0)
union sockaddr_any {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr_storage ss;
};
struct listen_socket
{
struct fi_info* fi;
struct fid_fabric *fabric;
struct fid_eq *eq;
struct fid_pep *pep;
int fd;
};
static const char *
sockaddrstr(const union sockaddr_any *addr, socklen_t len, char *buf, size_t buflen, unsigned short* port)
{
static char namebuf[BUFSIZ];
static char servbuf[BUFSIZ];
int errcode;
if ((errcode = getnameinfo(&addr->sa, len, namebuf, BUFSIZ,
servbuf, BUFSIZ,
NI_NUMERICHOST | NI_NUMERICSERV)))
{
if (errcode != EAI_SYSTEM) {
ERROR("getnameinfo failed: %s", gai_strerror(errcode));
} else {
ERROR("getnameinfo failed: %s", strerror(errno));
}
}
snprintf(buf, buflen, "%s", namebuf);
*port = atoi(servbuf);
return buf;
}
static void
print_endpoint(struct listen_socket* socket)
{
union sockaddr_any addr;
memset(&addr, 0, sizeof(addr));
size_t addrlen = sizeof(addr);
int ret;
if((ret = fi_getname(&socket->pep->fid, &addr, &addrlen)))
{
ERROR("fi_getname failed: %d '%s'", ret, fi_strerror(-ret));
}
char buf[128];
unsigned short port;
const char* straddr = sockaddrstr(&addr, addrlen, buf, 128, &port);
printf("endpoint = %s:%d\n", straddr, port);
}
void listen_server(struct listen_socket* socket, const char* address)
{
int ret;
struct epoll_event ev;
struct fi_info* hints;
struct fi_eq_attr eq_attr = {
.wait_obj = FI_WAIT_FD
};
hints = fi_allocinfo();
hints->ep_attr->type = FI_EP_MSG;
hints->caps = FI_MSG;
hints->mode = FI_LOCAL_MR;
if(ret = fi_getinfo(FI_VERSION(1, 0), address, "0", FI_SOURCE, hints, &socket->fi)) {
ERROR("fi_getinfo failed: %d '%s'", ret, fi_strerror(-ret));
}
//printf("info: %s\n", fi_tostr(socket->fi, FI_TYPE_INFO));
if(ret = fi_fabric(socket->fi->fabric_attr, &socket->fabric, NULL)) {
ERROR("fi_fabric failed: %d", ret);
}
if(ret = fi_eq_open(socket->fabric, &eq_attr, &socket->eq, NULL)) {
ERROR("fi_eq_open failed: %d", ret);
}
if(ret = fi_passive_ep(socket->fabric, socket->fi, &socket->pep, NULL)) {
ERROR("fi_passive_ep failed: %d", ret);
}
if(ret = fi_pep_bind(socket->pep, &socket->eq->fid, 0)) {
ERROR("fi_pep_bind failed: %d", ret);
}
if(ret = fi_listen(socket->pep)) {
ERROR("fi_listen failed: %d '%s'", ret, fi_strerror(-ret));
}
print_endpoint(socket);
}
int main()
{
int ret;
struct listen_socket lsocket;
listen_server(&lsocket, "127.0.0.1");
listen_server(&lsocket, "0.0.0.0");
return 0;
}
@joerns
Copy link
Author

joerns commented Mar 14, 2016

Output of the above program:

endpoint = 127.0.0.1:46542
endpoint = 137.138.90.204:0

The first time with the fixed IP address the port gets auto-assigned, but the second time not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment