Compare commits
12 Commits
ahc_fix_se
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
ef59212790 | ||
|
c8f1bd43ea | ||
|
60191543a3 | ||
|
048ec10308 | ||
|
00bf5dab6f | ||
|
6283eefbc9 | ||
|
536740a8d9 | ||
|
e82d0ab755 | ||
|
3209c7f9b1 | ||
|
adf8806ab9 | ||
|
e3077ba65c | ||
|
e57dfc478b |
@ -122,7 +122,7 @@ A list of all available options can be obtained by specifying the
|
|||||||
--help option (all option names can be abbreviated as long as they
|
--help option (all option names can be abbreviated as long as they
|
||||||
remain unambiguous).
|
remain unambiguous).
|
||||||
|
|
||||||
A more realistic test case might be to issue 1000 HTTP requests at a
|
A more realistic test case might be to issue 100 HTTP requests at a
|
||||||
rate of 10 requests per second. This can be achieved by additionally
|
rate of 10 requests per second. This can be achieved by additionally
|
||||||
specifying the --num-conns and --rate options. When specifying the
|
specifying the --num-conns and --rate options. When specifying the
|
||||||
--rate option, it's generally a good idea to also specify a timeout
|
--rate option, it's generally a good idea to also specify a timeout
|
||||||
|
@ -93,4 +93,9 @@ if test "$enable_debug" = yes; then
|
|||||||
CFLAGS="${CFLAGS} -DDEBUG"
|
CFLAGS="${CFLAGS} -DDEBUG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_WITH(epoll, AS_HELP_STRING([--with-epoll], [use epoll if available]))
|
||||||
|
AS_IF([test "$with_epoll" != "no"],
|
||||||
|
AC_CHECK_FUNC(epoll_create,
|
||||||
|
AC_DEFINE([HAVE_EPOLL], 1, [#undef HAVE_EPOLL])))
|
||||||
|
|
||||||
AC_OUTPUT(Makefile man/Makefile src/stat/Makefile src/lib/Makefile src/gen/Makefile src/Makefile)
|
AC_OUTPUT(Makefile man/Makefile src/stat/Makefile src/lib/Makefile src/gen/Makefile src/Makefile)
|
||||||
|
@ -122,6 +122,11 @@ conn_init(Conn *conn)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (param.tls_server_name)
|
||||||
|
{
|
||||||
|
SSL_set_tlsext_host_name(conn->ssl, param.tls_server_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (param.ssl_cipher_list) {
|
if (param.ssl_cipher_list) {
|
||||||
/* set order of ciphers */
|
/* set order of ciphers */
|
||||||
int ssl_err = SSL_set_cipher_list(conn->ssl, param.ssl_cipher_list);
|
int ssl_err = SSL_set_cipher_list(conn->ssl, param.ssl_cipher_list);
|
||||||
|
@ -108,6 +108,9 @@ typedef struct Conn
|
|||||||
|
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
SSL *ssl; /* SSL connection info */
|
SSL *ssl; /* SSL connection info */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
int epoll_added; /* is fd added into epoll? */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Conn;
|
Conn;
|
||||||
|
279
src/core.c
279
src/core.c
@ -49,12 +49,12 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
|
||||||
// You may need to override this!
|
|
||||||
// #define FD_SETSIZE 2048
|
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_KEVENT
|
#ifdef HAVE_KEVENT
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
|
|
||||||
@ -111,10 +111,17 @@ static u_long max_burst_len;
|
|||||||
#ifdef HAVE_KEVENT
|
#ifdef HAVE_KEVENT
|
||||||
static int kq, max_sd = 0;
|
static int kq, max_sd = 0;
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
#define EPOLL_N_MAX 8192
|
||||||
|
static int epoll_fd, max_sd = 0;
|
||||||
|
static struct epoll_event *epoll_events;
|
||||||
|
static int epoll_timeout;
|
||||||
|
#else
|
||||||
static fd_set rdfds, wrfds;
|
static fd_set rdfds, wrfds;
|
||||||
static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0;
|
static int min_sd = 0x7fffffff, max_sd = 0, alloced_sd_to_conn = 0;
|
||||||
static struct timeval select_timeout;
|
static struct timeval select_timeout;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
static struct sockaddr_in myaddr;
|
static struct sockaddr_in myaddr;
|
||||||
static struct address_pool myaddrs;
|
static struct address_pool myaddrs;
|
||||||
#ifndef HAVE_KEVENT
|
#ifndef HAVE_KEVENT
|
||||||
@ -155,12 +162,14 @@ static char http11req_nohost[] =
|
|||||||
enum Syscalls {
|
enum Syscalls {
|
||||||
SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,
|
SC_BIND, SC_CONNECT, SC_READ, SC_SELECT, SC_SOCKET, SC_WRITEV,
|
||||||
SC_SSL_READ, SC_SSL_WRITEV, SC_KEVENT,
|
SC_SSL_READ, SC_SSL_WRITEV, SC_KEVENT,
|
||||||
|
SC_EPOLL_CREATE, SC_EPOLL_CTL, SC_EPOLL_WAIT,
|
||||||
SC_NUM_SYSCALLS
|
SC_NUM_SYSCALLS
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const syscall_name[SC_NUM_SYSCALLS] = {
|
static const char *const syscall_name[SC_NUM_SYSCALLS] = {
|
||||||
"bind", "connct", "read", "select", "socket", "writev",
|
"bind", "connct", "read", "select", "socket", "writev",
|
||||||
"ssl_read", "ssl_writev", "kevent"
|
"ssl_read", "ssl_writev", "kevent",
|
||||||
|
"epoll_create", "epoll_ctl", "epoll_wait"
|
||||||
};
|
};
|
||||||
static Time syscall_time[SC_NUM_SYSCALLS];
|
static Time syscall_time[SC_NUM_SYSCALLS];
|
||||||
static u_int syscall_count[SC_NUM_SYSCALLS];
|
static u_int syscall_count[SC_NUM_SYSCALLS];
|
||||||
@ -377,6 +386,23 @@ clear_active(Conn * s, enum IO_DIR dir)
|
|||||||
"write" : "read");
|
"write" : "read");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
struct epoll_event ev;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (dir == WRITE)
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
else
|
||||||
|
ev.events = EPOLLOUT;
|
||||||
|
ev.data.ptr = s;
|
||||||
|
|
||||||
|
error = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sd, &ev);
|
||||||
|
if (error < 0) {
|
||||||
|
error = errno;
|
||||||
|
fprintf(stderr, "failed to EPOLL_CTL_DEL\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
fd_set * fdset;
|
fd_set * fdset;
|
||||||
|
|
||||||
@ -385,6 +411,7 @@ clear_active(Conn * s, enum IO_DIR dir)
|
|||||||
else
|
else
|
||||||
fdset = &rdfds;
|
fdset = &rdfds;
|
||||||
FD_CLR(sd, fdset);
|
FD_CLR(sd, fdset);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (dir == WRITE)
|
if (dir == WRITE)
|
||||||
s->writing = 0;
|
s->writing = 0;
|
||||||
@ -408,6 +435,28 @@ set_active(Conn * s, enum IO_DIR dir)
|
|||||||
"write" : "read");
|
"write" : "read");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
struct epoll_event ev;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (dir == WRITE)
|
||||||
|
ev.events = EPOLLOUT;
|
||||||
|
else
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
ev.data.ptr = s;
|
||||||
|
|
||||||
|
if (s->epoll_added)
|
||||||
|
error = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sd, &ev);
|
||||||
|
else {
|
||||||
|
error = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sd, &ev);
|
||||||
|
s->epoll_added = 1;
|
||||||
|
}
|
||||||
|
if (error < 0) {
|
||||||
|
error = errno;
|
||||||
|
fprintf(stderr, "failed to EPOLL_CTL_MOD\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
fd_set * fdset;
|
fd_set * fdset;
|
||||||
|
|
||||||
@ -418,6 +467,7 @@ set_active(Conn * s, enum IO_DIR dir)
|
|||||||
FD_SET(sd, fdset);
|
FD_SET(sd, fdset);
|
||||||
if (sd < min_sd)
|
if (sd < min_sd)
|
||||||
min_sd = sd;
|
min_sd = sd;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (sd >= max_sd)
|
if (sd >= max_sd)
|
||||||
max_sd = sd;
|
max_sd = sd;
|
||||||
@ -886,7 +936,7 @@ core_init(void)
|
|||||||
Any_Type arg;
|
Any_Type arg;
|
||||||
|
|
||||||
memset(&hash_table, 0, sizeof(hash_table));
|
memset(&hash_table, 0, sizeof(hash_table));
|
||||||
#ifndef HAVE_KEVENT
|
#if !defined(HAVE_KEVENT) && !defined(HAVE_EPOLL)
|
||||||
memset(&rdfds, 0, sizeof(rdfds));
|
memset(&rdfds, 0, sizeof(rdfds));
|
||||||
memset(&wrfds, 0, sizeof(wrfds));
|
memset(&wrfds, 0, sizeof(wrfds));
|
||||||
#endif
|
#endif
|
||||||
@ -926,6 +976,23 @@ core_init(void)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
epoll_fd = epoll_create(EPOLL_N_MAX);
|
||||||
|
if (epoll_fd < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: failed to create epoll: %s", prog_name,
|
||||||
|
strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
epoll_events = calloc(EPOLL_N_MAX, sizeof(struct epoll_event));
|
||||||
|
if (epoll_events == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: failed to create epoll_events: %s", prog_name,
|
||||||
|
strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
epoll_timeout = 0;
|
||||||
|
#else
|
||||||
#ifdef DONT_POLL
|
#ifdef DONT_POLL
|
||||||
/*
|
/*
|
||||||
* This causes select() to take several milliseconds on both Linux/x86
|
* This causes select() to take several milliseconds on both Linux/x86
|
||||||
@ -943,6 +1010,7 @@ core_init(void)
|
|||||||
select_timeout.tv_sec = 0;
|
select_timeout.tv_sec = 0;
|
||||||
select_timeout.tv_usec = 0;
|
select_timeout.tv_usec = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1080,15 +1148,6 @@ core_connect(Conn * s)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd > FD_SETSIZE) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s.core_connect.socket: sd > FD_SETSIZE (%d)\n",
|
|
||||||
prog_name,
|
|
||||||
FD_SETSIZE);
|
|
||||||
close(sd);
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
|
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
|
||||||
fprintf(stderr, "%s.core_connect.fcntl: %s\n",
|
fprintf(stderr, "%s.core_connect.fcntl: %s\n",
|
||||||
prog_name, strerror(errno));
|
prog_name, strerror(errno));
|
||||||
@ -1133,7 +1192,7 @@ core_connect(Conn * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->sd = sd;
|
s->sd = sd;
|
||||||
#ifndef HAVE_KEVENT
|
#if !defined(HAVE_KEVENT) && !defined(HAVE_EPOLL)
|
||||||
if (sd >= alloced_sd_to_conn) {
|
if (sd >= alloced_sd_to_conn) {
|
||||||
size_t size, old_size;
|
size_t size, old_size;
|
||||||
|
|
||||||
@ -1381,8 +1440,19 @@ core_close(Conn * conn)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sd >= 0) {
|
if (sd >= 0) {
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
|
struct epoll_event ev = { 0, { 0 } };
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, sd, &ev);
|
||||||
|
if (error < 0) {
|
||||||
|
error = errno;
|
||||||
|
printf("EPOLL_CTL_DEL: %d %d %d\n", epoll_fd, sd, error);
|
||||||
|
assert(error == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
close(sd);
|
close(sd);
|
||||||
#ifndef HAVE_KEVENT
|
#if !defined(HAVE_KEVENT) && !defined(HAVE_EPOLL)
|
||||||
sd_to_conn[sd] = 0;
|
sd_to_conn[sd] = 0;
|
||||||
FD_CLR(sd, &wrfds);
|
FD_CLR(sd, &wrfds);
|
||||||
FD_CLR(sd, &rdfds);
|
FD_CLR(sd, &rdfds);
|
||||||
@ -1458,57 +1528,66 @@ core_loop(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_EPOLL
|
||||||
static void
|
|
||||||
check_conn(int sd, int is_readable, int is_writable)
|
|
||||||
{
|
|
||||||
Conn *conn;
|
|
||||||
Any_Type arg;
|
|
||||||
|
|
||||||
/* Don't bother doing anything if we're not ready */
|
|
||||||
if ((is_readable || is_writable) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* only handle sockets that
|
|
||||||
* haven't timed out yet
|
|
||||||
*/
|
|
||||||
conn = sd_to_conn[sd];
|
|
||||||
conn_inc_ref(conn);
|
|
||||||
|
|
||||||
if (conn->watchdog) {
|
|
||||||
timer_cancel(conn->watchdog);
|
|
||||||
conn->watchdog = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->state == S_CONNECTING) {
|
|
||||||
#ifdef HAVE_SSL
|
|
||||||
if (param.use_ssl)
|
|
||||||
core_ssl_connect(conn);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (is_writable) {
|
|
||||||
clear_active(conn, WRITE);
|
|
||||||
conn->state = S_CONNECTED;
|
|
||||||
arg.l = 0;
|
|
||||||
event_signal(EV_CONN_CONNECTED, (Object*)conn, arg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (is_writable && conn->sendq)
|
|
||||||
do_send(conn);
|
|
||||||
if (is_readable && conn->recvq)
|
|
||||||
do_recv(conn);
|
|
||||||
}
|
|
||||||
conn_dec_ref(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
core_loop(void)
|
core_loop(void)
|
||||||
{
|
{
|
||||||
int is_readable, is_writable, n, sd;
|
struct epoll_event *ep;
|
||||||
|
int i, n;
|
||||||
|
Any_Type arg;
|
||||||
|
Conn *conn;
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
++iteration;
|
||||||
|
|
||||||
|
timer_tick();
|
||||||
|
n = epoll_wait(epoll_fd, epoll_events, EPOLL_N_MAX, epoll_timeout);
|
||||||
|
if (n < 0 && errno == EINTR) {
|
||||||
|
fprintf(stderr, "failed to fetch event: %s",
|
||||||
|
strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ep = epoll_events;
|
||||||
|
for (i = 0; i < n; i++, ep++) {
|
||||||
|
conn = ep->data.ptr;
|
||||||
|
conn_inc_ref(conn);
|
||||||
|
|
||||||
|
if (conn->watchdog) {
|
||||||
|
timer_cancel(conn->watchdog);
|
||||||
|
conn->watchdog = 0;
|
||||||
|
}
|
||||||
|
if (conn->state == S_CONNECTING) {
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (param.use_ssl)
|
||||||
|
core_ssl_connect(conn);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (ep->events & EPOLLOUT) {
|
||||||
|
clear_active(conn, WRITE);
|
||||||
|
conn->state = S_CONNECTED;
|
||||||
|
arg.l = 0;
|
||||||
|
event_signal(EV_CONN_CONNECTED, (Object*)conn, arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ep->events & (EPOLLIN | EPOLLHUP) && conn->recvq)
|
||||||
|
do_recv(conn);
|
||||||
|
if (ep->events & EPOLLOUT && conn->sendq)
|
||||||
|
do_send(conn);
|
||||||
|
}
|
||||||
|
conn_dec_ref(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(epoll_fd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
core_loop(void)
|
||||||
|
{
|
||||||
|
int is_readable, is_writable, n, sd, bit, min_i, max_i, i = 0;
|
||||||
fd_set readable, writable;
|
fd_set readable, writable;
|
||||||
fd_mask mask;
|
fd_mask mask;
|
||||||
|
Any_Type arg;
|
||||||
|
Conn *conn;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
struct timeval tv = select_timeout;
|
struct timeval tv = select_timeout;
|
||||||
@ -1517,6 +1596,8 @@ core_loop(void)
|
|||||||
|
|
||||||
readable = rdfds;
|
readable = rdfds;
|
||||||
writable = wrfds;
|
writable = wrfds;
|
||||||
|
min_i = min_sd / NFDBITS;
|
||||||
|
max_i = max_sd / NFDBITS;
|
||||||
|
|
||||||
SYSCALL(SELECT, n = select(max_sd + 1, &readable, &writable, 0, &tv));
|
SYSCALL(SELECT, n = select(max_sd + 1, &readable, &writable, 0, &tv));
|
||||||
|
|
||||||
@ -1530,22 +1611,72 @@ core_loop(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX totally suboptimal loop, but less potentially problematic */
|
while (n > 0) {
|
||||||
|
/*
|
||||||
|
* find the index of the fdmask that has something
|
||||||
|
* going on:
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
if (i > max_i)
|
||||||
|
i = min_i;
|
||||||
|
|
||||||
for (sd = 0; sd <= max_sd; sd++) {
|
assert(i <= max_i);
|
||||||
is_readable = (FD_ISSET(sd, &readable) && FD_ISSET(sd, &rdfds));
|
mask = readable.fds_bits[i] | writable.fds_bits[i];
|
||||||
is_writable = (FD_ISSET(sd, &writable) && FD_ISSET(sd, &wrfds));
|
} while (!mask);
|
||||||
if (is_readable || is_writable)
|
bit = 0;
|
||||||
check_conn(sd, is_readable, is_writable);
|
sd = i * NFDBITS + bit;
|
||||||
|
do {
|
||||||
|
if (mask & 1) {
|
||||||
|
--n;
|
||||||
|
is_readable = (FD_ISSET(sd, &readable) && FD_ISSET(sd, &rdfds));
|
||||||
|
is_writable = (FD_ISSET(sd, &writable) && FD_ISSET(sd, &wrfds));
|
||||||
|
|
||||||
|
if (is_readable || is_writable) {
|
||||||
|
/*
|
||||||
|
* only handle sockets that
|
||||||
|
* haven't timed out yet
|
||||||
|
*/
|
||||||
|
conn = sd_to_conn[sd];
|
||||||
|
conn_inc_ref(conn);
|
||||||
|
|
||||||
/* XXX TODO: totally can bail out if we've seen 'n' FDs */
|
if (conn->watchdog) {
|
||||||
}
|
timer_cancel(conn->watchdog);
|
||||||
|
conn->watchdog = 0;
|
||||||
/* Do timer tick at the end of the connection check */
|
}
|
||||||
timer_tick();
|
if (conn->state == S_CONNECTING) {
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (param.use_ssl)
|
||||||
|
core_ssl_connect(conn);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (is_writable) {
|
||||||
|
clear_active(conn, WRITE);
|
||||||
|
conn->state = S_CONNECTED;
|
||||||
|
arg.l = 0;
|
||||||
|
event_signal(EV_CONN_CONNECTED, (Object*)conn, arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_writable && conn->sendq)
|
||||||
|
do_send(conn);
|
||||||
|
if (is_readable && conn->recvq)
|
||||||
|
do_recv(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn_dec_ref(conn);
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
timer_tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask = ((u_long) mask) >> 1;
|
||||||
|
++sd;
|
||||||
|
} while (mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
core_exit(void)
|
core_exit(void)
|
||||||
|
@ -144,6 +144,7 @@ static struct option longopts[] = {
|
|||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
{"ssl", no_argument, ¶m.use_ssl, 1},
|
{"ssl", no_argument, ¶m.use_ssl, 1},
|
||||||
{"ssl-ciphers", required_argument, (int *) ¶m.ssl_cipher_list, 0},
|
{"ssl-ciphers", required_argument, (int *) ¶m.ssl_cipher_list, 0},
|
||||||
|
{"tls-server-name", required_argument, (int *) ¶m.tls_server_name, 0},
|
||||||
{"ssl-no-reuse", no_argument, ¶m.ssl_reuse, 0},
|
{"ssl-no-reuse", no_argument, ¶m.ssl_reuse, 0},
|
||||||
{"ssl-certificate", required_argument, (int *) ¶m.ssl_cert, 0},
|
{"ssl-certificate", required_argument, (int *) ¶m.ssl_cert, 0},
|
||||||
{"ssl-key", required_argument, (int *) ¶m.ssl_key, 0},
|
{"ssl-key", required_argument, (int *) ¶m.ssl_key, 0},
|
||||||
@ -668,6 +669,8 @@ main(int argc, char **argv)
|
|||||||
param.ssl_ca_path = optarg;
|
param.ssl_ca_path = optarg;
|
||||||
else if (flag == ¶m.ssl_protocol)
|
else if (flag == ¶m.ssl_protocol)
|
||||||
{
|
{
|
||||||
|
param.use_ssl = 1;
|
||||||
|
|
||||||
if (strcasecmp (optarg, "auto") == 0)
|
if (strcasecmp (optarg, "auto") == 0)
|
||||||
param.ssl_protocol = 0;
|
param.ssl_protocol = 0;
|
||||||
#ifndef OPENSSL_NO_SSL2
|
#ifndef OPENSSL_NO_SSL2
|
||||||
@ -684,7 +687,7 @@ main(int argc, char **argv)
|
|||||||
param.ssl_protocol = 5;
|
param.ssl_protocol = 5;
|
||||||
else if (strcasecmp (optarg, "TLSv1.2") == 0 || strcasecmp (optarg, "TLSv1_2") == 0)
|
else if (strcasecmp (optarg, "TLSv1.2") == 0 || strcasecmp (optarg, "TLSv1_2") == 0)
|
||||||
param.ssl_protocol = 6;
|
param.ssl_protocol = 6;
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
#ifdef TLS1_3_VERSION
|
||||||
else if (strcasecmp (optarg, "TLSv1.3") == 0 || strcasecmp (optarg, "TLSv1_3") == 0)
|
else if (strcasecmp (optarg, "TLSv1.3") == 0 || strcasecmp (optarg, "TLSv1_3") == 0)
|
||||||
param.ssl_protocol = 7;
|
param.ssl_protocol = 7;
|
||||||
#endif
|
#endif
|
||||||
@ -695,6 +698,19 @@ main(int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (flag == ¶m.tls_server_name)
|
||||||
|
{
|
||||||
|
if (param.ssl_protocol >= 4)
|
||||||
|
{
|
||||||
|
param.tls_server_name = optarg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: Error setting the SNI (Server Name Indication) server name to %s. The --tls-server-name option can only be used if --ssl-protocol-version is set to TLSv1.0 and above.\n",
|
||||||
|
prog_name, optarg);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (flag == ¶m.uri)
|
else if (flag == ¶m.uri)
|
||||||
param.uri = optarg;
|
param.uri = optarg;
|
||||||
@ -1060,7 +1076,7 @@ main(int argc, char **argv)
|
|||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_VERSION);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
ssl_ctx = SSL_CTX_new (TLSv1_client_method ()); break;
|
ssl_ctx = SSL_CTX_new (TLSv1_client_method ());
|
||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); break;
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2); break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1072,7 +1088,7 @@ main(int argc, char **argv)
|
|||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_1_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_1_VERSION);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
ssl_ctx = SSL_CTX_new (TLSv1_client_method ()); break;
|
ssl_ctx = SSL_CTX_new (TLSv1_client_method ());
|
||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2); break;
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2); break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1084,12 +1100,13 @@ main(int argc, char **argv)
|
|||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_2_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_2_VERSION);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
ssl_ctx = SSL_CTX_new (TLSv1_client_method ()); break;
|
ssl_ctx = SSL_CTX_new (TLSv1_client_method ());
|
||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); break;
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
#ifdef TLS1_3_VERSION
|
||||||
/* 7/TLSv1.3 */
|
/* 7/TLSv1.3 */
|
||||||
|
case 7:
|
||||||
ssl_ctx = SSL_CTX_new (TLS_client_method ());
|
ssl_ctx = SSL_CTX_new (TLS_client_method ());
|
||||||
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
@ -1291,6 +1308,8 @@ main(int argc, char **argv)
|
|||||||
printf(" --ssl");
|
printf(" --ssl");
|
||||||
if (param.ssl_cipher_list)
|
if (param.ssl_cipher_list)
|
||||||
printf(" --ssl-ciphers=%s", param.ssl_cipher_list);
|
printf(" --ssl-ciphers=%s", param.ssl_cipher_list);
|
||||||
|
if (param.tls_server_name)
|
||||||
|
printf(" --tls-server-name=%s", param.tls_server_name);
|
||||||
if (!param.ssl_reuse)
|
if (!param.ssl_reuse)
|
||||||
printf(" --ssl-no-reuse");
|
printf(" --ssl-no-reuse");
|
||||||
if (param.ssl_cert) printf (" --ssl-cert=%s", param.ssl_cert);
|
if (param.ssl_cert) printf (" --ssl-cert=%s", param.ssl_cert);
|
||||||
@ -1310,7 +1329,7 @@ main(int argc, char **argv)
|
|||||||
case 4: printf (" --ssl-protocol=TLSv1.0"); break;
|
case 4: printf (" --ssl-protocol=TLSv1.0"); break;
|
||||||
case 5: printf (" --ssl-protocol=TLSv1.1"); break;
|
case 5: printf (" --ssl-protocol=TLSv1.1"); break;
|
||||||
case 6: printf (" --ssl-protocol=TLSv1.2"); break;
|
case 6: printf (" --ssl-protocol=TLSv1.2"); break;
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
|
#ifdef TLS1_3_VERSION
|
||||||
case 7: printf (" --ssl-protocol=TLSv1.3"); break;
|
case 7: printf (" --ssl-protocol=TLSv1.3"); break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,7 @@ typedef struct Cmdline_Params
|
|||||||
int ssl_reuse; /* reuse SSL Session ID */
|
int ssl_reuse; /* reuse SSL Session ID */
|
||||||
int ssl_verify; /* whether to verify the server certificate */
|
int ssl_verify; /* whether to verify the server certificate */
|
||||||
int ssl_protocol; /* which SSL protocol to use */
|
int ssl_protocol; /* which SSL protocol to use */
|
||||||
|
const char *tls_server_name; /* TLS SNI (server name indication) */
|
||||||
const char *ssl_cipher_list; /* client's list of SSL cipher suites */
|
const char *ssl_cipher_list; /* client's list of SSL cipher suites */
|
||||||
const char *ssl_cert; /* client certificate file name */
|
const char *ssl_cert; /* client certificate file name */
|
||||||
const char *ssl_key; /* client key file name */
|
const char *ssl_key; /* client key file name */
|
||||||
|
Loading…
Reference in New Issue
Block a user