Skip to content

Commit

Permalink
anet.c: new API anetTcpNonBlockBestEffortBindConnect()
Browse files Browse the repository at this point in the history
This performs a best effort source address binding attempt. If it is
possible to bind the local address and still have a successful
connect(), then this socket is returned. Otherwise the call is retried
without source address binding attempt.

Related to issues #2609 and #2612.
  • Loading branch information
antirez committed Jun 11, 2015
1 parent 8283d63 commit 308939e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/anet.c
Expand Up @@ -264,6 +264,7 @@ static int anetCreateSocket(char *err, int domain) {

#define ANET_CONNECT_NONE 0
#define ANET_CONNECT_NONBLOCK 1
#define ANET_CONNECT_BE_BINDING 2 /* Best effort binding. */
static int anetTcpGenericConnect(char *err, char *addr, int port,
char *source_addr, int flags)
{
Expand Down Expand Up @@ -331,9 +332,17 @@ static int anetTcpGenericConnect(char *err, char *addr, int port,
close(s);
s = ANET_ERR;
}

end:
freeaddrinfo(servinfo);
return s;

/* Handle best effort binding: if a binding address was used, but it is
* not possible to create a socket, try again without a binding address. */
if (s == ANET_ERR && source_addr && (flags & ANET_CONNECT_BE_BINDING)) {
return anetTcpGenericConnect(err,addr,port,NULL,flags);
} else {
return s;
}
}

int anetTcpConnect(char *err, char *addr, int port)
Expand All @@ -346,9 +355,18 @@ int anetTcpNonBlockConnect(char *err, char *addr, int port)
return anetTcpGenericConnect(err,addr,port,NULL,ANET_CONNECT_NONBLOCK);
}

int anetTcpNonBlockBindConnect(char *err, char *addr, int port, char *source_addr)
int anetTcpNonBlockBindConnect(char *err, char *addr, int port,
char *source_addr)
{
return anetTcpGenericConnect(err,addr,port,source_addr,
ANET_CONNECT_NONBLOCK);
}

int anetTcpNonBlockBestEffortBindConnect(char *err, char *addr, int port,
char *source_addr)
{
return anetTcpGenericConnect(err,addr,port,source_addr,ANET_CONNECT_NONBLOCK);
return anetTcpGenericConnect(err,addr,port,source_addr,
ANET_CONNECT_NONBLOCK|ANET_CONNECT_BE_BINDING);
}

int anetUnixGenericConnect(char *err, char *path, int flags)
Expand Down
1 change: 1 addition & 0 deletions src/anet.h
Expand Up @@ -50,6 +50,7 @@
int anetTcpConnect(char *err, char *addr, int port);
int anetTcpNonBlockConnect(char *err, char *addr, int port);
int anetTcpNonBlockBindConnect(char *err, char *addr, int port, char *source_addr);
int anetTcpNonBlockBestEffortBindConnect(char *err, char *addr, int port, char *source_addr);
int anetUnixConnect(char *err, char *path);
int anetUnixNonBlockConnect(char *err, char *path);
int anetRead(int fd, char *buf, int count);
Expand Down

0 comments on commit 308939e

Please sign in to comment.