*************************************************/
/* Copyright (c) Jeremy Harris 2015 - 2018 */
+/* Copyright (c) The Exim Maintainers 2021 */
/* See the file NOTICE for conditions of use and distribution. */
/* SOCKS version 5 proxy, client-mode */
#ifdef TCP_QUICKACK
(void) setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
#endif
- if (!fd_ready(fd, tmo-time(NULL)) || read(fd, s, 2) != 2)
+ if (!fd_ready(fd, tmo) || read(fd, s, 2) != 2)
return FAIL;
HDEBUG(D_transport|D_acl|D_v)
debug_printf_indent(" SOCKS<< %02x %02x\n", s[0], s[1]);
socks_opts * lim = &proxies[nproxies];
long rnd, weights;
unsigned pri;
-static BOOL srandomed = FALSE;
if (nproxies == 1) /* shortcut, if we have only 1 server */
return (proxies[0].is_failed ? -1 : 0);
-/* init random */
-if (!srandomed)
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- srandom((unsigned int)(tv.tv_usec/1000));
- srandomed = TRUE;
- }
-
/* scan for highest pri */
for (pri = 0, sd = proxies; sd < lim; sd++)
if (!sd->is_failed && sd->priority > pri)
if (weights == 0) /* all servers failed */
return -1;
-for (rnd = random() % weights, i = 0; i < nproxies; i++)
+for (rnd = random_number(weights), i = 0; i < nproxies; i++)
{
sd = &proxies[i];
if (!sd->is_failed && sd->priority == pri)
- if ((rnd -= sd->weight) <= 0)
+ if ((rnd -= sd->weight) < 0)
return i;
}
uschar buf[24];
socks_opts proxies[32]; /* max #proxies handled */
unsigned nproxies;
-socks_opts * sob;
+socks_opts * sob = NULL;
unsigned size;
blob early_data;
while ((option = string_nextinlist(&proxy_spec, &subsep, NULL, 0)))
socks_option(sob, option);
}
+if (!sob) return -1;
/* Set up the socks protocol method-selection message,
for sending on connection */
(void) setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
#endif
-if ( !fd_ready(fd, tmo-time(NULL))
+if ( !fd_ready(fd, tmo)
|| read(fd, buf, 2) != 2
)
goto rcv_err;
/* expect conn-reply (success, local(ipver, addr, port))
of same length as conn-request, or non-success fail code */
-if ( !fd_ready(fd, tmo-time(NULL))
+if ( !fd_ready(fd, tmo)
|| (size = read(fd, buf, size)) < 2
)
goto rcv_err;