Commit 72d0bc84 authored by Matt Caswell's avatar Matt Caswell
Browse files

Add a -sctp option to s_server

parent 5114d822
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@
#define PORT            "4433"
#define PROTOCOL        "tcp"

typedef int (*do_server_cb)(int s, int stype, unsigned char *context);
typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
int do_server(int *accept_sock, const char *host, const char *port,
              int family, int type,
              int family, int type, int protocol,
              do_server_cb cb,
              unsigned char *context, int naccept);
#ifdef HEADER_X509_H
+52 −14
Original line number Diff line number Diff line
@@ -91,9 +91,9 @@ typedef unsigned int u_int;
#endif

static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
static int sv_body(int s, int stype, unsigned char *context);
static int www_body(int s, int stype, unsigned char *context);
static int rev_body(int s, int stype, unsigned char *context);
static int sv_body(int s, int stype, int prot, unsigned char *context);
static int www_body(int s, int stype, int prot, unsigned char *context);
static int rev_body(int s, int stype, int prot, unsigned char *context);
static void close_accept_socket(void);
static int init_ssl_connection(SSL *s);
static void print_stats(BIO *bp, SSL_CTX *ctx);
@@ -719,7 +719,7 @@ typedef enum OPTION_choice {
    OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
    OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
    OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
    OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
    OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
    OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
    OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
    OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
@@ -903,6 +903,9 @@ const OPTIONS s_server_options[] = {
#ifndef OPENSSL_NO_DTLS1_2
    {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
#endif
#ifndef OPENSSL_NO_SCTP
    {"sctp", OPT_SCTP, '-', "Use SCTP"},
#endif
#ifndef OPENSSL_NO_DH
    {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
#endif
@@ -960,7 +963,7 @@ int s_server_main(int argc, char *argv[])
    int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
    int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
    int rev = 0, naccept = -1, sdebug = 0;
    int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
    int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
    int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
    char *host = NULL;
    char *port = BUF_strdup(PORT);
@@ -1429,6 +1432,11 @@ int s_server_main(int argc, char *argv[])
            min_version = DTLS1_2_VERSION;
            max_version = DTLS1_2_VERSION;
            socket_type = SOCK_DGRAM;
#endif
            break;
        case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
            protocol = IPPROTO_SCTP;
#endif
            break;
        case OPT_TIMEOUT:
@@ -1543,6 +1551,17 @@ int s_server_main(int argc, char *argv[])
    }
#endif

#ifndef OPENSSL_NO_SCTP
    if (protocol == IPPROTO_SCTP) {
        if (socket_type != SOCK_DGRAM) {
            BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
            goto end;
        }
        /* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
        socket_type = SOCK_STREAM;
    }
#endif

    if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
        BIO_printf(bio_err, "Bad split send fragment size\n");
        goto end;
@@ -2018,7 +2037,7 @@ int s_server_main(int argc, char *argv[])
        && unlink_unix_path)
        unlink(host);
#endif
    do_server(&accept_socket, host, port, socket_family, socket_type,
    do_server(&accept_socket, host, port, socket_family, socket_type, protocol,
              server_cb, context, naccept);
    print_stats(bio_s_out, ctx);
    ret = 0;
@@ -2090,7 +2109,7 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
               SSL_CTX_sess_get_cache_size(ssl_ctx));
}

static int sv_body(int s, int stype, unsigned char *context)
static int sv_body(int s, int stype, int prot, unsigned char *context)
{
    char *buf = NULL;
    fd_set readfds;
@@ -2105,6 +2124,13 @@ static int sv_body(int s, int stype, unsigned char *context)
#else
    struct timeval *timeoutp;
#endif
#ifndef OPENSSL_NO_DTLS
 #ifndef OPENSSL_NO_SCTP
    int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP);
 #else
    int isdtls = (stype == SOCK_DGRAM);
 #endif
#endif

    buf = app_malloc(bufsize, "server buffer");
    if (s_nbio) {
@@ -2136,8 +2162,12 @@ static int sv_body(int s, int stype, unsigned char *context)
        goto err;
    }
#ifndef OPENSSL_NO_DTLS
    if (stype == SOCK_DGRAM) {

    if (isdtls) {
#ifndef OPENSSL_NO_SCTP
        if (prot == IPPROTO_SCTP)
            sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
        else
#endif
            sbio = BIO_new_dgram(s, BIO_NOCLOSE);

        if (enable_timeouts) {
@@ -2169,12 +2199,20 @@ static int sv_body(int s, int stype, unsigned char *context)
            /* want to do MTU discovery */
            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);

        /* turn on cookie exchange */
        if (prot != IPPROTO_SCTP) {
            /* Turn on cookie exchange. Not necessary for SCTP */
            SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
        }
    } else
#endif
        sbio = BIO_new_socket(s, BIO_NOCLOSE);

    if (sbio == NULL) {
        BIO_printf(bio_err, "Unable to create BIO\n");
        ERR_print_errors(bio_err);
        goto err;
    }

    if (s_nbio_test) {
        BIO *test;

@@ -2767,7 +2805,7 @@ static DH *load_dh_param(const char *dhfile)
}
#endif

static int www_body(int s, int stype, unsigned char *context)
static int www_body(int s, int stype, int prot, unsigned char *context)
{
    char *buf = NULL;
    int ret = 1;
@@ -3153,7 +3191,7 @@ static int www_body(int s, int stype, unsigned char *context)
    return (ret);
}

static int rev_body(int s, int stype, unsigned char *context)
static int rev_body(int s, int stype, int prot, unsigned char *context)
{
    char *buf = NULL;
    int i;
+26 −5
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ int init_client(int *sock, const char *host, const char *port,
 * 0 on failure, something other on success.
 */
int do_server(int *accept_sock, const char *host, const char *port,
              int family, int type, do_server_cb cb,
              int family, int type, int protocol, do_server_cb cb,
              unsigned char *context, int naccept)
{
    int asock = 0;
@@ -140,7 +140,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
    if (!BIO_sock_init())
        return 0;

    if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
    if (!BIO_lookup_ex(host, port, BIO_LOOKUP_SERVER, family, type, protocol,
                       &res)) {
        ERR_print_errors(bio_err);
        return 0;
    }
@@ -148,7 +149,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
    /* Admittedly, these checks are quite paranoid, we should not get
     * anything in the BIO_ADDRINFO chain that we haven't asked for */
    OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
                   && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
                   && (type == 0 || type == BIO_ADDRINFO_socktype(res))
                   && (protocol == 0 || protocol == BIO_ADDRINFO_protocol(res)));

    asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
                       BIO_ADDRINFO_protocol(res), 0);
@@ -161,6 +163,25 @@ int do_server(int *accept_sock, const char *host, const char *port,
        goto end;
    }

#ifndef OPENSSL_NO_SCTP
    if (protocol == IPPROTO_SCTP) {
        /*
         * For SCTP we have to set various options on the socket prior to
         * accepting. This is done automatically by BIO_new_dgram_sctp().
         * We don't actually need the created BIO though so we free it again
         * immediately.
         */
        BIO *tmpbio = BIO_new_dgram_sctp(asock, BIO_NOCLOSE);

        if (tmpbio == NULL) {
            BIO_closesocket(asock);
            ERR_print_errors(bio_err);
            goto end;
        }
        BIO_free(tmpbio);
    }
#endif

    BIO_ADDRINFO_free(res);
    res = NULL;

@@ -176,10 +197,10 @@ int do_server(int *accept_sock, const char *host, const char *port,
                BIO_closesocket(asock);
                break;
            }
            i = (*cb)(sock, type, context);
            i = (*cb)(sock, type, protocol, context);
            BIO_closesocket(sock);
        } else {
            i = (*cb)(asock, type, context);
            i = (*cb)(asock, type, protocol, context);
        }

        if (naccept != -1)