[openib-general] Re: Re: [PATCH] CMA: allow/require bind beforeconnect

Michael S. Tsirkin mst at mellanox.co.il
Wed Mar 29 11:23:51 PST 2006


Quoting Sean Hefty <sean.hefty at intel.com>:
> >> What behavior are you expected from rdma_bind_addr() if you specify a zero
> >> IP address?  loopback IP address?
> >
> >ANY - bind to all IP addresses. This then gets put in SDP hello message,
> >returned to user by socket query, and is marked reserved for other binds.
> 
> You lost me here.  Put all IP addresses in the SDP hello message?  An IP address
> of 0?

Sorry. I attach a code snippet as an example.
Assume I bind to IP 127.0.0.1 and port number 1289.

Connection source port then gets put in hello message local port field.

When you actually connect and resolve the route we need to put the
IP address of the IB device in there, since that the only way the passive side
will know what our IP address is.

> And you're reserving ... the specified port number?

Yes, in the sense that another bind to this same port on
same IP address will fail.

-- 
Michael S. Tsirkin
Staff Engineer, Mellanox Technologies
-------------- next part --------------
#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <malloc.h>
#include <getopt.h>
#include <arpa/inet.h>
#include <time.h>


int main(int argc, char **argv)
{
	int rc = 0;
	struct addrinfo *res, *t;
	struct addrinfo hints = {
		.ai_family   = AF_INET,
		.ai_socktype = SOCK_STREAM
	};
	char *service;
	char *servername;
	char *port;
	int n;
	int sockfd = -1;
	int ai_family;

	if (argc - 1 < 3) {
		fprintf(stderr, "Usage: %s <protocol> <server> < port>\n",
			argv[0]);
		return 2;
	}

	struct protoent *proto = getprotobyname(argv[1]);
	if (proto) {
		fprintf(stderr, "protocol: %s, %d\n",
			proto->p_name, proto->p_proto);
	} else {
		fprintf(stderr, "protocol %s not found\n", argv[1]);
		return 1;
	}

	servername = argv[2];
	port = argv[3];

	ai_family = (proto->p_proto > 255) ? 27 : AF_INET;
	sockfd = socket(ai_family, SOCK_STREAM, 0);
	if (sockfd < 0) {
		perror("unable to create socket:");
		exit(1);
	}

	n = getaddrinfo(NULL, "1289", &hints, &res);

	if (n < 0) {
		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
		return 1;
	}


	for (t = res; t; t = t->ai_next) {
		if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
			break;
		perror("bind failed:");
		close(sockfd);
		sockfd = -1;
	}

	n = getaddrinfo(servername, port, &hints, &res);

	if (n < 0) {
		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
		return 1;
	}


	for (t = res; t; t = t->ai_next) {
		if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
			break;
		perror("connect failed:");
		close(sockfd);
		sockfd = -1;
	}

	sleep(2);

	freeaddrinfo(res);

	if (sockfd < 0) {
		fprintf(stderr, "Couldn't connect to %s:%s\n", servername, port);
		return 5;
	}

	sleep(2);

	return rc;
}


More information about the general mailing list