Commit 87cb4ae7 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Have VTCP_connect() also call socket(2), I have no idea why it didn't

just do that from the start.
parent e5261b28
...@@ -85,49 +85,13 @@ VBE_ReleaseConn(struct vbc *vc) ...@@ -85,49 +85,13 @@ VBE_ReleaseConn(struct vbc *vc)
dst = cache_param->tmx; \ dst = cache_param->tmx; \
} while (0) } while (0)
/*--------------------------------------------------------------------
* Attempt to connect to a given addrinfo entry.
*
* Must be called with locked backend, but will release the backend
* lock during the slow/sleeping stuff, so that other worker threads
* can have a go, while we ponder.
*
*/
static int
vbe_TryConnect(const struct busyobj *bo, int pf,
const struct suckaddr *sa, const struct vbe_dir *vs)
{
int s, i, tmo;
double tmod;
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
s = socket(pf, SOCK_STREAM, 0);
if (s < 0)
return (s);
FIND_TMO(connect_timeout, tmod, bo, vs->vrt);
tmo = (int)(tmod * 1000.0);
i = VTCP_connect(s, sa, tmo);
if (i != 0) {
AZ(close(s));
return (-1);
}
return (s);
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void static void
bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vbe_dir *vs) bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vbe_dir *vs)
{ {
int s; int s, msec;
double tmod;
struct backend *bp = vs->backend; struct backend *bp = vs->backend;
char abuf1[VTCP_ADDRBUFSIZE]; char abuf1[VTCP_ADDRBUFSIZE];
char pbuf1[VTCP_PORTBUFSIZE]; char pbuf1[VTCP_PORTBUFSIZE];
...@@ -146,16 +110,19 @@ bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vbe_dir *vs) ...@@ -146,16 +110,19 @@ bes_conn_try(struct busyobj *bo, struct vbc *vc, const struct vbe_dir *vs)
/* release lock during stuff that can take a long time */ /* release lock during stuff that can take a long time */
FIND_TMO(connect_timeout, tmod, bo, vs->vrt);
msec = (int)floor(tmod * 1000.0);
if (cache_param->prefer_ipv6 && bp->ipv6 != NULL) { if (cache_param->prefer_ipv6 && bp->ipv6 != NULL) {
s = vbe_TryConnect(bo, PF_INET6, bp->ipv6, vs); s = VTCP_connect(bp->ipv6, msec);
vc->addr = bp->ipv6; vc->addr = bp->ipv6;
} }
if (s == -1 && bp->ipv4 != NULL) { if (s == -1 && bp->ipv4 != NULL) {
s = vbe_TryConnect(bo, PF_INET, bp->ipv4, vs); s = VTCP_connect(bp->ipv4, msec);
vc->addr = bp->ipv4; vc->addr = bp->ipv4;
} }
if (s == -1 && !cache_param->prefer_ipv6 && bp->ipv6 != NULL) { if (s == -1 && !cache_param->prefer_ipv6 && bp->ipv6 != NULL) {
s = vbe_TryConnect(bo, PF_INET6, bp->ipv6, vs); s = VTCP_connect(bp->ipv6, msec);
vc->addr = bp->ipv6; vc->addr = bp->ipv6;
} }
......
...@@ -104,22 +104,6 @@ static struct lock vbp_mtx; ...@@ -104,22 +104,6 @@ static struct lock vbp_mtx;
* want to measure the backends response without local distractions. * want to measure the backends response without local distractions.
*/ */
static int
vbp_connect(int pf, const struct suckaddr *sa, int tmo)
{
int s, i;
s = socket(pf, SOCK_STREAM, 0);
if (s < 0)
return (s);
i = VTCP_connect(s, sa, tmo);
if (i == 0)
return (s);
VTCP_close(&s);
return (-1);
}
static void static void
vbp_poke(struct vbp_target *vt) vbp_poke(struct vbp_target *vt)
{ {
...@@ -139,21 +123,21 @@ vbp_poke(struct vbp_target *vt) ...@@ -139,21 +123,21 @@ vbp_poke(struct vbp_target *vt)
s = -1; s = -1;
if (cache_param->prefer_ipv6 && bp->ipv6 != NULL) { if (cache_param->prefer_ipv6 && bp->ipv6 != NULL) {
s = vbp_connect(PF_INET6, bp->ipv6, tmo); s = VTCP_connect(bp->ipv6, tmo);
t_now = VTIM_real(); t_now = VTIM_real();
tmo = (int)round((t_end - t_now) * 1e3); tmo = (int)round((t_end - t_now) * 1e3);
if (s >= 0) if (s >= 0)
vt->good_ipv6 |= 1; vt->good_ipv6 |= 1;
} }
if (tmo > 0 && s < 0 && bp->ipv4 != NULL) { if (tmo > 0 && s < 0 && bp->ipv4 != NULL) {
s = vbp_connect(PF_INET, bp->ipv4, tmo); s = VTCP_connect(bp->ipv4, tmo);
t_now = VTIM_real(); t_now = VTIM_real();
tmo = (int)round((t_end - t_now) * 1e3); tmo = (int)round((t_end - t_now) * 1e3);
if (s >= 0) if (s >= 0)
vt->good_ipv4 |= 1; vt->good_ipv4 |= 1;
} }
if (tmo > 0 && s < 0 && bp->ipv6 != NULL) { if (tmo > 0 && s < 0 && bp->ipv6 != NULL) {
s = vbp_connect(PF_INET6, bp->ipv6, tmo); s = VTCP_connect(bp->ipv6, tmo);
t_now = VTIM_real(); t_now = VTIM_real();
tmo = (int)round((t_end - t_now) * 1e3); tmo = (int)round((t_end - t_now) * 1e3);
if (s >= 0) if (s >= 0)
......
...@@ -69,7 +69,7 @@ int VTCP_check_hup(int sock); ...@@ -69,7 +69,7 @@ int VTCP_check_hup(int sock);
#ifdef SOL_SOCKET #ifdef SOL_SOCKET
void VTCP_name(const struct suckaddr *addr, char *abuf, unsigned alen, void VTCP_name(const struct suckaddr *addr, char *abuf, unsigned alen,
char *pbuf, unsigned plen); char *pbuf, unsigned plen);
int VTCP_connect(int s, const struct suckaddr *name, int msec); int VTCP_connect(const struct suckaddr *name, int msec);
void VTCP_close(int *s); void VTCP_close(int *s);
void VTCP_set_read_timeout(int s, double seconds); void VTCP_set_read_timeout(int s, double seconds);
#endif #endif
...@@ -212,26 +212,37 @@ VTCP_nonblocking(int sock) ...@@ -212,26 +212,37 @@ VTCP_nonblocking(int sock)
*/ */
int int
VTCP_connect(int s, const struct suckaddr *name, int msec) VTCP_connect(const struct suckaddr *name, int msec)
{ {
int i, k; int s, i, k;
socklen_t l; socklen_t l;
struct pollfd fds[1]; struct pollfd fds[1];
const struct sockaddr *sa; const struct sockaddr *sa;
socklen_t sl; socklen_t sl;
assert(s >= 0); if (name == NULL)
return (-1);
/* Attempt the connect */
AN(VSA_Sane(name));
sa = VSA_Get_Sockaddr(name, &sl);
AN(sa);
AN(sl);
s = socket(sa->sa_family, SOCK_STREAM, 0);
if (s < 0)
return (s);
/* Set the socket non-blocking */ /* Set the socket non-blocking */
if (msec > 0) if (msec > 0)
(void)VTCP_nonblocking(s); (void)VTCP_nonblocking(s);
/* Attempt the connect */
AN(VSA_Sane(name));
sa = VSA_Get_Sockaddr(name, &sl);
i = connect(s, sa, sl); i = connect(s, sa, sl);
if (i == 0 || errno != EINPROGRESS) if (i == 0)
return (i); return (s);
if (errno != EINPROGRESS) {
AZ(close(s));
return (-1);
}
assert(msec > 0); assert(msec > 0);
/* Exercise our patience, polling for write */ /* Exercise our patience, polling for write */
...@@ -242,6 +253,7 @@ VTCP_connect(int s, const struct suckaddr *name, int msec) ...@@ -242,6 +253,7 @@ VTCP_connect(int s, const struct suckaddr *name, int msec)
if (i == 0) { if (i == 0) {
/* Timeout, close and give up */ /* Timeout, close and give up */
AZ(close(s));
errno = ETIMEDOUT; errno = ETIMEDOUT;
return (-1); return (-1);
} }
...@@ -252,11 +264,13 @@ VTCP_connect(int s, const struct suckaddr *name, int msec) ...@@ -252,11 +264,13 @@ VTCP_connect(int s, const struct suckaddr *name, int msec)
/* An error means no connection established */ /* An error means no connection established */
errno = k; errno = k;
if (k) if (k) {
AZ(close(s));
return (-1); return (-1);
}
(void)VTCP_blocking(s); (void)VTCP_blocking(s);
return (0); return (s);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment