Merge branch 'libtls-tests'
Improves handling failures during unit tests of libtls and includes a change for the openssl plugin so it only announces ECDH groups for which the library provides the required ECC curve. Closes strongswan/strongswan#752
This commit is contained in:
@@ -328,49 +328,52 @@ METHOD(diffie_hellman_t, destroy, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header
|
||||||
|
*/
|
||||||
|
int openssl_ecdh_group_to_nid(diffie_hellman_group_t group)
|
||||||
|
{
|
||||||
|
switch (group)
|
||||||
|
{
|
||||||
|
case ECP_192_BIT:
|
||||||
|
return NID_X9_62_prime192v1;
|
||||||
|
case ECP_224_BIT:
|
||||||
|
return NID_secp224r1;
|
||||||
|
case ECP_256_BIT:
|
||||||
|
return NID_X9_62_prime256v1;
|
||||||
|
case ECP_384_BIT:
|
||||||
|
return NID_secp384r1;
|
||||||
|
case ECP_521_BIT:
|
||||||
|
return NID_secp521r1;
|
||||||
|
/* added with 1.0.2 */
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
case ECP_224_BP:
|
||||||
|
return NID_brainpoolP224r1;
|
||||||
|
case ECP_256_BP:
|
||||||
|
return NID_brainpoolP256r1;
|
||||||
|
case ECP_384_BP:
|
||||||
|
return NID_brainpoolP384r1;
|
||||||
|
case ECP_512_BP:
|
||||||
|
return NID_brainpoolP512r1;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header
|
||||||
*/
|
*/
|
||||||
openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
|
openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
|
||||||
{
|
{
|
||||||
private_openssl_ec_diffie_hellman_t *this;
|
private_openssl_ec_diffie_hellman_t *this;
|
||||||
EC_KEY *key = NULL;
|
EC_KEY *key = NULL;
|
||||||
|
int curve;
|
||||||
|
|
||||||
switch (group)
|
curve = openssl_ecdh_group_to_nid(group);
|
||||||
|
if (curve)
|
||||||
{
|
{
|
||||||
case ECP_192_BIT:
|
key = EC_KEY_new_by_curve_name(curve);
|
||||||
key = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
|
|
||||||
break;
|
|
||||||
case ECP_224_BIT:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_secp224r1);
|
|
||||||
break;
|
|
||||||
case ECP_256_BIT:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
|
||||||
break;
|
|
||||||
case ECP_384_BIT:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_secp384r1);
|
|
||||||
break;
|
|
||||||
case ECP_521_BIT:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_secp521r1);
|
|
||||||
break;
|
|
||||||
/* added with 1.0.2 */
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
case ECP_224_BP:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_brainpoolP224r1);
|
|
||||||
break;
|
|
||||||
case ECP_256_BP:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_brainpoolP256r1);
|
|
||||||
break;
|
|
||||||
case ECP_384_BP:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_brainpoolP384r1);
|
|
||||||
break;
|
|
||||||
case ECP_512_BP:
|
|
||||||
key = EC_KEY_new_by_curve_name(NID_brainpoolP512r1);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key)
|
if (!key)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -408,4 +411,5 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro
|
|||||||
}
|
}
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* OPENSSL_NO_EC */
|
#endif /* OPENSSL_NO_EC */
|
||||||
|
|||||||
@@ -44,5 +44,12 @@ struct openssl_ec_diffie_hellman_t {
|
|||||||
*/
|
*/
|
||||||
openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group);
|
openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group);
|
||||||
|
|
||||||
#endif /** OPENSSL_EC_DIFFIE_HELLMAN_H_ @}*/
|
/**
|
||||||
|
* Map ECDH groups to OpenSSL NIDs for the ECC curve.
|
||||||
|
*
|
||||||
|
* @param group ECDH group
|
||||||
|
* @return NID for the curve
|
||||||
|
*/
|
||||||
|
int openssl_ecdh_group_to_nid(diffie_hellman_group_t group);
|
||||||
|
|
||||||
|
#endif /** OPENSSL_EC_DIFFIE_HELLMAN_H_ @}*/
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
|
#include <openssl/ec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "openssl_plugin.h"
|
#include "openssl_plugin.h"
|
||||||
#include "openssl_util.h"
|
#include "openssl_util.h"
|
||||||
@@ -486,10 +489,55 @@ METHOD(plugin_t, get_name, char*,
|
|||||||
return "openssl";
|
return "openssl";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
|
/**
|
||||||
|
* Check if the given DH group is in the list of supported curves.
|
||||||
|
*/
|
||||||
|
static bool ecdh_group_supported(EC_builtin_curve *curves, size_t num_curves,
|
||||||
|
diffie_hellman_group_t group)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < num_curves; j++)
|
||||||
|
{
|
||||||
|
if (curves[j].nid == openssl_ecdh_group_to_nid(group))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only add features for ECDH groups that are actually supported.
|
||||||
|
*/
|
||||||
|
static void add_ecdh_features(plugin_feature_t *features,
|
||||||
|
plugin_feature_t *to_add, int count, int *pos)
|
||||||
|
{
|
||||||
|
size_t num_curves;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
num_curves = EC_get_builtin_curves(NULL, 0);
|
||||||
|
|
||||||
|
EC_builtin_curve curves[num_curves];
|
||||||
|
|
||||||
|
num_curves = EC_get_builtin_curves(curves, num_curves);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (to_add[i].kind != FEATURE_PROVIDE ||
|
||||||
|
ecdh_group_supported(curves, num_curves, to_add[i].arg.dh_group))
|
||||||
|
{
|
||||||
|
features[(*pos)++] = to_add[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* OPENSSL_NO_ECDH */
|
||||||
|
|
||||||
METHOD(plugin_t, get_features, int,
|
METHOD(plugin_t, get_features, int,
|
||||||
private_openssl_plugin_t *this, plugin_feature_t *features[])
|
private_openssl_plugin_t *this, plugin_feature_t *features[])
|
||||||
{
|
{
|
||||||
static plugin_feature_t f[] = {
|
static plugin_feature_t f_base[] = {
|
||||||
/* we provide OpenSSL threading callbacks */
|
/* we provide OpenSSL threading callbacks */
|
||||||
PLUGIN_PROVIDE(CUSTOM, "openssl-threading"),
|
PLUGIN_PROVIDE(CUSTOM, "openssl-threading"),
|
||||||
/* crypters */
|
/* crypters */
|
||||||
@@ -635,21 +683,6 @@ METHOD(plugin_t, get_features, int,
|
|||||||
PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
|
PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
|
||||||
#endif /* OPENSSL_NO_CHACHA */
|
#endif /* OPENSSL_NO_CHACHA */
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
#ifndef OPENSSL_NO_ECDH
|
|
||||||
/* EC DH groups */
|
|
||||||
PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_256_BIT),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_384_BIT),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_521_BIT),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_224_BIT),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_192_BIT),
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_256_BP),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_384_BP),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_512_BP),
|
|
||||||
PLUGIN_PROVIDE(DH, ECP_224_BP),
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
#endif /* OPENSSL_NO_ECDH */
|
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
/* MODP DH groups */
|
/* MODP DH groups */
|
||||||
PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
|
PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
|
||||||
@@ -809,6 +842,33 @@ METHOD(plugin_t, get_features, int,
|
|||||||
PLUGIN_PROVIDE(RNG, RNG_STRONG),
|
PLUGIN_PROVIDE(RNG, RNG_STRONG),
|
||||||
PLUGIN_PROVIDE(RNG, RNG_WEAK),
|
PLUGIN_PROVIDE(RNG, RNG_WEAK),
|
||||||
};
|
};
|
||||||
|
static plugin_feature_t f_ecdh[] = {
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
|
/* EC DH groups */
|
||||||
|
PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_256_BIT),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_384_BIT),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_521_BIT),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_224_BIT),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_192_BIT),
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_256_BP),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_384_BP),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_512_BP),
|
||||||
|
PLUGIN_PROVIDE(DH, ECP_224_BP),
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
#endif /* OPENSSL_NO_ECDH */
|
||||||
|
};
|
||||||
|
static plugin_feature_t f[countof(f_base) + countof(f_ecdh)] = {};
|
||||||
|
static int count = 0;
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
plugin_features_add(f, f_base, countof(f_base), &count);
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
|
add_ecdh_features(f, f_ecdh, countof(f_ecdh), &count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
*features = f;
|
*features = f;
|
||||||
return countof(f);
|
return countof(f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,14 +366,6 @@ START_SETUP(setup_all_creds)
|
|||||||
}
|
}
|
||||||
END_SETUP
|
END_SETUP
|
||||||
|
|
||||||
START_TEARDOWN(teardown_creds)
|
|
||||||
{
|
|
||||||
lib->credmgr->remove_set(lib->credmgr, &creds->set);
|
|
||||||
creds->destroy(creds);
|
|
||||||
creds = NULL;
|
|
||||||
}
|
|
||||||
END_TEARDOWN
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for an echo server
|
* Configuration for an echo server
|
||||||
*/
|
*/
|
||||||
@@ -386,6 +378,27 @@ typedef struct {
|
|||||||
bool cauth;
|
bool cauth;
|
||||||
} echo_server_config_t;
|
} echo_server_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global server config for current test
|
||||||
|
*/
|
||||||
|
static echo_server_config_t *server_config;
|
||||||
|
|
||||||
|
START_TEARDOWN(teardown_creds)
|
||||||
|
{
|
||||||
|
lib->credmgr->remove_set(lib->credmgr, &creds->set);
|
||||||
|
creds->destroy(creds);
|
||||||
|
creds = NULL;
|
||||||
|
|
||||||
|
if (server_config)
|
||||||
|
{
|
||||||
|
shutdown(server_config->fd, SHUT_RDWR);
|
||||||
|
close(server_config->fd);
|
||||||
|
free(server_config);
|
||||||
|
server_config = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEARDOWN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run an echo server
|
* Run an echo server
|
||||||
*/
|
*/
|
||||||
@@ -545,28 +558,22 @@ static echo_server_config_t *create_config(tls_version_t version, uint16_t port,
|
|||||||
*/
|
*/
|
||||||
static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i)
|
static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i)
|
||||||
{
|
{
|
||||||
echo_server_config_t *config;
|
|
||||||
tls_cipher_suite_t *suites;
|
tls_cipher_suite_t *suites;
|
||||||
char suite[128];
|
char suite[128];
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
config = create_config(version, port, cauth);
|
server_config = create_config(version, port, cauth);
|
||||||
|
|
||||||
start_echo_server(config);
|
start_echo_server(server_config);
|
||||||
|
|
||||||
count = tls_crypto_get_supported_suites(TRUE, version, &suites);
|
count = tls_crypto_get_supported_suites(TRUE, version, &suites);
|
||||||
ck_assert(i < count);
|
ck_assert(i < count);
|
||||||
snprintf(suite, sizeof(suite), "%N", tls_cipher_suite_names, suites[i]);
|
snprintf(suite, sizeof(suite), "%N", tls_cipher_suite_names, suites[i]);
|
||||||
lib->settings->set_str(lib->settings, "%s.tls.suites", suite, lib->ns);
|
lib->settings->set_str(lib->settings, "%s.tls.suites", suite, lib->ns);
|
||||||
|
|
||||||
run_echo_client(config);
|
run_echo_client(server_config);
|
||||||
|
|
||||||
free(suites);
|
free(suites);
|
||||||
|
|
||||||
shutdown(config->fd, SHUT_RDWR);
|
|
||||||
close(config->fd);
|
|
||||||
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -575,14 +582,13 @@ static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i)
|
|||||||
static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth,
|
static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth,
|
||||||
u_int i)
|
u_int i)
|
||||||
{
|
{
|
||||||
echo_server_config_t *config;
|
|
||||||
diffie_hellman_group_t *groups;
|
diffie_hellman_group_t *groups;
|
||||||
char curve[128];
|
char curve[128];
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
config = create_config(version, port, cauth);
|
server_config = create_config(version, port, cauth);
|
||||||
|
|
||||||
start_echo_server(config);
|
start_echo_server(server_config);
|
||||||
|
|
||||||
count = tls_crypto_get_supported_groups(&groups);
|
count = tls_crypto_get_supported_groups(&groups);
|
||||||
ck_assert(i < count);
|
ck_assert(i < count);
|
||||||
@@ -590,14 +596,9 @@ static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth,
|
|||||||
groups[i]);
|
groups[i]);
|
||||||
lib->settings->set_str(lib->settings, "%s.tls.ke_group", curve, lib->ns);
|
lib->settings->set_str(lib->settings, "%s.tls.ke_group", curve, lib->ns);
|
||||||
|
|
||||||
run_echo_client(config);
|
run_echo_client(server_config);
|
||||||
|
|
||||||
free(groups);
|
free(groups);
|
||||||
|
|
||||||
shutdown(config->fd, SHUT_RDWR);
|
|
||||||
close(config->fd);
|
|
||||||
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -606,14 +607,13 @@ static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth,
|
|||||||
static void test_tls_signature_schemes(tls_version_t version, uint16_t port,
|
static void test_tls_signature_schemes(tls_version_t version, uint16_t port,
|
||||||
bool cauth, u_int i)
|
bool cauth, u_int i)
|
||||||
{
|
{
|
||||||
echo_server_config_t *config;
|
|
||||||
tls_signature_scheme_t *schemes;
|
tls_signature_scheme_t *schemes;
|
||||||
char signature[128];
|
char signature[128];
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
config = create_config(version, port, cauth);
|
server_config = create_config(version, port, cauth);
|
||||||
|
|
||||||
start_echo_server(config);
|
start_echo_server(server_config);
|
||||||
|
|
||||||
count = tls_crypto_get_supported_signatures(version, &schemes);
|
count = tls_crypto_get_supported_signatures(version, &schemes);
|
||||||
ck_assert(i < count);
|
ck_assert(i < count);
|
||||||
@@ -621,14 +621,9 @@ static void test_tls_signature_schemes(tls_version_t version, uint16_t port,
|
|||||||
schemes[i]);
|
schemes[i]);
|
||||||
lib->settings->set_str(lib->settings, "%s.tls.signature", signature, lib->ns);
|
lib->settings->set_str(lib->settings, "%s.tls.signature", signature, lib->ns);
|
||||||
|
|
||||||
run_echo_client(config);
|
run_echo_client(server_config);
|
||||||
|
|
||||||
free(schemes);
|
free(schemes);
|
||||||
|
|
||||||
shutdown(config->fd, SHUT_RDWR);
|
|
||||||
close(config->fd);
|
|
||||||
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -637,22 +632,19 @@ static void test_tls_signature_schemes(tls_version_t version, uint16_t port,
|
|||||||
static void test_tls_server(tls_version_t version, uint16_t port, bool cauth,
|
static void test_tls_server(tls_version_t version, uint16_t port, bool cauth,
|
||||||
u_int i)
|
u_int i)
|
||||||
{
|
{
|
||||||
echo_server_config_t *client, *server;
|
echo_server_config_t *client;
|
||||||
|
|
||||||
|
server_config = create_config(version, port, cauth);
|
||||||
client = create_config(i, port, cauth);
|
client = create_config(i, port, cauth);
|
||||||
server = create_config(version, port, cauth);
|
|
||||||
|
|
||||||
start_echo_server(server);
|
start_echo_server(server_config);
|
||||||
|
|
||||||
run_echo_client(client);
|
run_echo_client(client);
|
||||||
|
|
||||||
shutdown(client->fd, SHUT_RDWR);
|
shutdown(client->fd, SHUT_RDWR);
|
||||||
close(client->fd);
|
close(client->fd);
|
||||||
shutdown(server->fd, SHUT_RDWR);
|
|
||||||
close(server->fd);
|
|
||||||
|
|
||||||
free(client);
|
free(client);
|
||||||
free(server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -661,22 +653,19 @@ static void test_tls_server(tls_version_t version, uint16_t port, bool cauth,
|
|||||||
static void test_tls_client(tls_version_t version, uint16_t port, bool cauth,
|
static void test_tls_client(tls_version_t version, uint16_t port, bool cauth,
|
||||||
u_int i)
|
u_int i)
|
||||||
{
|
{
|
||||||
echo_server_config_t *client, *server;
|
echo_server_config_t *client;
|
||||||
|
|
||||||
|
server_config = create_config(i, port, cauth);
|
||||||
client = create_config(version, port, cauth);
|
client = create_config(version, port, cauth);
|
||||||
server = create_config(i, port, cauth);
|
|
||||||
|
|
||||||
start_echo_server(server);
|
start_echo_server(server_config);
|
||||||
|
|
||||||
run_echo_client(client);
|
run_echo_client(client);
|
||||||
|
|
||||||
shutdown(client->fd, SHUT_RDWR);
|
shutdown(client->fd, SHUT_RDWR);
|
||||||
close(client->fd);
|
close(client->fd);
|
||||||
shutdown(server->fd, SHUT_RDWR);
|
|
||||||
close(server->fd);
|
|
||||||
|
|
||||||
free(client);
|
free(client);
|
||||||
free(server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(test_tls_12_server)
|
START_TEST(test_tls_12_server)
|
||||||
|
|||||||
@@ -193,11 +193,13 @@ static bool exchange(private_tls_socket_t *this, bool wr, bool block)
|
|||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
if (wr)
|
if (!wr && this->app.in_done > 0)
|
||||||
{
|
{ /* return data after proper termination via fatal close
|
||||||
return FALSE;
|
* notify to which we responded with one */
|
||||||
|
this->eof = TRUE;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
break;
|
return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user