56RCSID(
"$Id: 57ea0bacf592519657600199da53e554812a8b5c $")
58#include <freeradius-devel/server/base.h>
59#include <freeradius-devel/server/module_rlm.h>
61#include <freeradius-devel/io/listen.h>
62#include <freeradius-devel/io/thread.h>
64#include <freeradius-devel/tls/base.h>
65#include <freeradius-devel/tls/strerror.h>
66#include <freeradius-devel/tls/version.h>
67#include <freeradius-devel/tls/connection.h>
69#include <freeradius-devel/unlang/base.h>
70#include <freeradius-devel/unlang/function.h>
71#include <freeradius-devel/unlang/interpret.h>
73#include <freeradius-devel/util/socket.h>
75#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
81#define EXIT_WITH_FAILURE \
95 { .out = &
dict_tls, .proto =
"tls" },
198 RDEBUG3(
"Initialising internal request");
212 RDEBUG3(
"Done external request");
223 RDEBUG3(
"Done internal request");
230 RDEBUG3(
"Done detached request");
286 if (utt->
done)
return;
289 utt->
ret = conn->failed ? EXIT_FAILURE : EXIT_SUCCESS;
301 utt->
conn->failed =
true;
315 fr_tls_session_t *tls_session = conn->tls_session;
330 if (errno == EINTR)
continue;
337 ERROR(
"Wrote no data to connection");
347 DEBUG3(
"Wrote %zd bytes to the connection", slen);
361 uint8_t buf[SSL3_RT_MAX_PLAIN_LENGTH];
364 if (utt->
done)
return;
366 slen = read(fd, buf,
sizeof(buf));
368 if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK))
return;
376 ERROR(
"Connection closed by the peer before the handshake completed");
392 if (fr_tls_session_alert(utt->
conn->request, utt->
conn->tls_session,
393 SSL3_AL_FATAL, SSL_AD_ACCESS_DENIED) < 0) {
394 ERROR(
"Failed raising the TLS alert");
400 fr_tls_connection_recv(utt->
conn, buf, (
size_t) slen);
435 if (request == utt->
conn->request) {
436 fr_tls_connection_process(utt->
conn);
450 fr_tls_session_is_init_finished(utt->
conn->tls_session)) {
451 INFO(
"Rejecting the session after a successful handshake");
452 utt->
conn->failed =
true;
456 if (utt->
done)
return;
473 if ((ipaddr.
af == AF_UNSPEC) || !port) {
474 ERROR(
"Both 'ipaddr' and 'port' must be set in the 'unit_test_tls' section "
475 "when listening for a connection");
481 PERROR(
"Failed opening TCP socket");
486 PERROR(
"Failed binding TCP socket");
491 if (listen(
sockfd, 8) < 0) {
568 talloc_steal(client, cs);
582 struct sockaddr_storage sa;
585 static uint64_t number = 0;
588 if (!request)
return NULL;
590 if (!request->packet) request->packet =
fr_packet_alloc(request,
false);
593 request->packet->timestamp =
fr_time();
595 request->packet->socket.type = SOCK_STREAM;
596 request->packet->socket.fd = fd;
599 if (getpeername(fd, (
struct sockaddr *) &sa, &salen) == 0) {
601 &request->packet->socket.inet.src_port, &sa, salen);
602 request->packet->socket.af = request->packet->socket.inet.src_ipaddr.af;
606 if (getsockname(fd, (
struct sockaddr *) &sa, &salen) == 0) {
608 &request->packet->socket.inet.dst_port, &sa, salen);
614 request->client =
tls_client_alloc(request, &request->packet->socket.inet.src_ipaddr);
615 if (!request->client) {
620 request->number = number++;
624 request->log.dst = talloc_zero(request,
log_dst_t);
630 request->async = talloc_zero(request,
fr_async_t);
631 request->async->request = request;
634 ERROR(
"Failed converting connection addresses to attributes");
656 PERROR(
"Failed adding the connection to the event loop");
666 fr_tls_connection_wake(utt->
conn);
684 utt->
conn->state = TLS_CONNECTION_NEW_SESSION;
685 utt->
conn->pending = utt->
conn->failed = utt->
conn->idle =
false;
686 utt->
conn->request = NULL;
687 utt->
conn->tls_session = NULL;
690 utt->
ret = EXIT_SUCCESS;
697 if (utt->
conn->client) {
700 INFO(
"Waiting for a connection");
702 utt->
fd = accept(utt->
sockfd, NULL, NULL);
710 if (!utt->
conn->request)
goto finish;
720 if (utt->
conn->client) {
721 utt->
conn->tls_session = fr_tls_session_alloc_client(utt->
conn->request, utt->
ssl_ctx, utt->
conn->request);
723 INFO(
"Accepted connection from %pV",
726 utt->
conn->tls_session = fr_tls_session_alloc_server(utt->
conn->request, utt->
ssl_ctx, utt->
conn->request,
730 if (!utt->
conn->tls_session) {
731 PERROR(
"Failed creating the TLS session");
741 if (fr_tls_connection_push(utt->
conn) < 0) {
742 PERROR(
"Failed starting new TLS connection");
749 PERROR(
"Failed adding the runnable handler to the event loop");
762 PERROR(
"Failed scheduling the start of the connection");
793 TALLOC_FREE(utt->
conn->tls_session);
794 TALLOC_FREE(utt->
conn->request);
804int main(
int argc,
char *argv[])
806 int ret = EXIT_SUCCESS;
809 char const *server = NULL;
810 unsigned int count = 1;
816 TALLOC_CTX *thread_ctx;
844 p = strrchr(argv[0], FR_DIR_SEP);
877 while ((c = getopt(argc, argv,
"Ac:Cd:D:hMn:r:Rs:xX")) != -1) {
888 count = (
unsigned int) atoi(optarg);
890 fprintf(stderr,
"Invalid value \"%s\" for -c\n", optarg);
912 talloc_enable_leak_report();
994 PERROR(
"Failed to initialize the dictionaries");
1013 PERROR(
"Failed initialising main event loop");
1036 utt->
ret = EXIT_SUCCESS;
1047 MEM(utt->
conn = talloc_zero(utt, fr_tls_connection_t));
1048 utt->
conn->uctx = utt;
1063 ERROR(
"Cannot find a top-level 'unit_test_tls { ... }' section in %s.conf",
config->name);
1070 cf_log_perr(utt_cs,
"Failed parsing the 'unit_test_tls' section");
1079 utt->
conn->client =
true;
1082 -1, AF_UNSPEC,
true,
false) < 0) {
1083 PERROR(
"Invalid value \"%s\" for -s", server);
1094 ERROR(
"No port given in -s, and no 'port' in the 'unit_test_tls' section");
1109 ERROR(
"Cannot find virtual server 'tls'");
1115 ERROR(
"Virtual server 'tls' must have 'namespace = tls'");
1128 if (utt->
conn->client) {
1131 ERROR(
"Cannot find a top-level 'tls client { ... }' section in %s.conf",
1136 utt->
conn->tls_conf = fr_tls_conf_parse_client(tls_cs);
1147 ERROR(
"Cannot find a top-level 'tls server { ... }' or 'tls { ... }' section in %s.conf",
1152 utt->
conn->tls_conf = fr_tls_conf_parse_server(tls_cs);
1155 if (!utt->
conn->tls_conf) {
1156 cf_log_perr(tls_cs,
"Failed parsing the TLS configuration");
1160 utt->
ssl_ctx = fr_tls_ctx_alloc(utt->
conn->tls_conf, utt->
conn->client);
1162 cf_log_perr(tls_cs,
"Failed creating the TLS context");
1170 DEBUG(
"Configuration appears to be OK");
1228 .init_internal = _request_init_internal,
1230 .done_external = _request_done_external,
1231 .done_internal = _request_done_internal,
1232 .done_detached = _request_done_detached,
1234 .detach = _request_detach,
1235 .yield = _request_yield,
1236 .resume = _request_resume,
1237 .mark_runnable = _request_runnable,
1238 .scheduled = _request_scheduled,
1258 for (i = 0; i < utt->
count; i++) {
1261 if (utt->
ret != EXIT_SUCCESS)
break;
1285 ERROR(
"Failed setting up coordinator close events");
1353 FILE *output = status ? stderr : stdout;
1355 fprintf(output,
"Usage: %s [options]\n",
config->name);
1356 fprintf(output,
"Options:\n");
1357 fprintf(output,
" -A Reject the peer with a fatal TLS alert on the last connection,\n");
1358 fprintf(output,
" rather than completing the handshake. With -c 2 the first\n");
1359 fprintf(output,
" connection fills the session cache, so the alert then has a\n");
1360 fprintf(output,
" session to clear. Used to test the alert and clear paths.\n");
1361 fprintf(output,
" -R Reject the session once the handshake has succeeded on the last\n");
1362 fprintf(output,
" connection, as policy would. The cached session is then cleared\n");
1363 fprintf(output,
" rather than stored. With -c 2 the first connection fills the\n");
1364 fprintf(output,
" cache and the second resumes from it before being rejected, so\n");
1365 fprintf(output,
" the clear then has a loaded session to remove.\n");
1366 fprintf(output,
" -c <count> Run <count> connections, one after another. Session resumption\n");
1367 fprintf(output,
" needs two: one to fill the cache, one to resume from it.\n");
1368 fprintf(output,
" -C Check configuration and exit.\n");
1369 fprintf(output,
" -d <confdir> Configuration file directory. (defaults to " CONFDIR
").\n");
1370 fprintf(output,
" -D <dict_dir> Dictionary files are in \"dict_dir/*\".\n");
1371 fprintf(output,
" -h Print this help message.\n");
1372 fprintf(output,
" -M Enable talloc leak reporting.\n");
1373 fprintf(output,
" -n <name> Read ${confdir}/name.conf instead of ${confdir}/unit_test_tls.conf.\n");
1374 fprintf(output,
" -r <receipt_file> Create <receipt_file> when the program exits successfully.\n");
1375 fprintf(output,
" -s <server[:port]> Connect to <server> as a TLS client, instead of listening\n");
1376 fprintf(output,
" for a connection. Reads the 'tls client' section. The port\n");
1377 fprintf(output,
" defaults to 'port' from the 'unit_test_tls' section.\n");
1378 fprintf(output,
" -X Turn on full debugging.\n");
1379 fprintf(output,
" -x Turn on additional debugging. (-xx gives more debugging).\n");
static int const char char buffer[256]
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
#define fr_atexit_thread_trigger_all(...)
#define NEVER_RETURNS
Should be placed before the function return type.
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define cf_section_rules_push(_cs, _rule)
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
CONF_PAIR * cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value, fr_token_t op, fr_token_t lhs_quote, fr_token_t rhs_quote)
Allocate a CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
#define cf_log_perr(_cf, _fmt,...)
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
int fr_coords_create(TALLOC_CTX *ctx, fr_event_list_t *el)
Start coordinators in single threaded mode.
void fr_coords_destroy(void)
Clean up coordinators in single threaded mode.
int fr_coord_close_event_insert(fr_event_list_t *el)
int fr_coord_post_event_insert(fr_event_list_t *el)
Insert instance specific post-event callbacks.
int fr_coord_pre_event_insert(fr_event_list_t *el)
Insert instance specific pre-event callbacks.
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
static char panic_action[512]
The command to execute when panicking.
void fr_disable_null_tracking_on_free(TALLOC_CTX *ctx)
Disable the null tracking context when a talloc chunk is freed.
void fr_talloc_fault_setup(void)
Register talloc fault handlers.
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program, unsigned long fault_signals)
Registers signal handlers to execute panic_action on fatal signal.
#define PANIC_ACTION_SIGNALS
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
void dependency_version_print(void)
static NEVER_RETURNS void usage(void)
#define fr_dict_autofree(_to_free)
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir, char const *dependent))
(Re-)Initialize the special internal dictionary
bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2)
See if two dictionaries have the same end parent.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_read(fr_dict_t *dict, char const *dict_dir, char const *filename))
Read supplementary attribute definitions into an existing dictionary.
int fr_dict_free(fr_dict_t **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
#define fr_dict_autoload(_to_load)
#define DICT_AUTOLOAD_TERMINATOR
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir))
Initialise the global protocol hashes.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define fr_event_fd_insert(...)
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
#define fr_event_user_insert(_ctx, _el, _ev_p, _trigger, _callback, _uctx)
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
int fr_heap_pop(void **out, fr_heap_t **hp)
Remove a node from the heap.
static bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
#define fr_heap_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init)
Creates a heap that verifies elements are of a specific talloc type.
int fr_ipaddr_from_sockaddr(fr_ipaddr_t *ipaddr, uint16_t *port, struct sockaddr_storage const *sa, socklen_t salen)
Convert sockaddr to our internal ip address representation.
bool fr_hostname_lookups
hostname -> IP lookups?
int fr_inet_pton_port(fr_ipaddr_t *out, uint16_t *port_out, char const *value, ssize_t inlen, int af, bool resolve, bool mask)
Parses IPv4/6 address + port, to fr_ipaddr_t and integer (port)
char * fr_inet_ntop(char out[static FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print the address portion of a fr_ipaddr_t.
bool fr_reverse_lookups
IP -> hostname lookups?
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
rlm_rcode_t unlang_interpret(request_t *request, bool running)
Run the interpreter for a current request.
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
void unlang_interpret_set_thread_default(unlang_interpret_t *intp)
Set the default interpreter for this thread.
unlang_interpret_t * unlang_interpret_init(TALLOC_CTX *ctx, fr_event_list_t *el, unlang_request_func_t *funcs, void *uctx)
Initialize a unlang compiler / interpret.
void unlang_interpret_signal(request_t *request, fr_signal_t action)
Send a signal (usually stop) to a request.
#define UNLANG_REQUEST_RESUME
External functions provided by the owner of the interpret.
int server_init(CONF_SECTION *cs, char const *conf_dir, fr_dict_t *dict)
Initialize src/lib/server/.
void server_free(void)
Free src/lib/server/.
Describes a host allowed to send packets to the server.
void vlog_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt, va_list ap, void *uctx)
Send a log message to its destination, possibly including fields from the request.
#define RPEDEBUG(fmt,...)
int fr_packet_pairs_from_packet(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_packet_t const *packet)
Allocate a "Net." struct with src/dst host and port.
int unlang_global_init(void)
int fr_event_post_delete(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx)
Delete a post-event callback from the event list.
unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t timeout, int signal)
Send a signal to all the processes we have in our reap list, and reap them.
void fr_event_loop_exit(fr_event_list_t *el, int code)
Signal an event loop exit with the specified code.
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
int fr_event_loop(fr_event_list_t *el)
Run an event loop.
int fr_event_post_insert(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx)
Add a post-event callback to the event list.
A file descriptor/filter event.
Stores all information relating to an event list.
Callbacks for kevent() user events.
int fr_unlink(char const *filename)
Remove a regular file from the filesystem.
ssize_t fr_touch(int *fd_out, char const *filename, mode_t mode, bool mkdir, mode_t dir_mode)
Create an empty file.
@ L_DST_STDOUT
Log to stdout.
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
Minimal data structure to use the new code.
int main_config_free(main_config_t **config)
main_config_t * main_config_alloc(TALLOC_CTX *ctx)
Allocate a main_config_t struct, setting defaults.
void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config)
Set the server name.
int main_config_init(main_config_t *config)
void main_config_confdir_set(main_config_t *config, char const *name)
Set the global radius config directory.
void main_config_dict_dir_set(main_config_t *config, char const *name)
Set the global dictionary directory.
Main server configuration.
fr_event_list_t * main_loop_event_list(void)
Return the main loop event list.
int main_loop_init(void)
Initialise the main event loop, setting up signal handlers.
void main_loop_free(void)
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
fr_cmp_ret_t fr_pointer_cmp(void const *a, void const *b)
Compares two pointers.
int modules_rlm_coord_attach(fr_event_list_t *el)
Runs the coord_attach method of all registered backend modules.
int modules_rlm_free(void)
Cleanup all global structures.
int modules_rlm_coord_detach(void)
Runs the coord_detach method of all registered backend modules.
int modules_rlm_init(void)
Initialise the module list structure.
static const conf_parser_t config[]
rlm_rcode_t
Return codes indicating the result of the module call.
int request_global_init(void)
int request_detach(request_t *child)
Unlink a subrequest from its parent.
#define request_local_alloc_internal(_ctx, _args)
Allocate a new internal request outside of the request pool.
@ REQUEST_ACTIVE
Request is active (running or runnable)
void fr_schedule_worker_id_set(int id)
Explicitly set the worker id for the current thread.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
int fr_socket_server_tcp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
Open an IPv4/IPv6 TCP socket.
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
int fr_socket_bind(int sockfd, char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port)
Bind a UDP/TCP v4/v6 socket to a given ipaddr src port, and interface.
fr_client_t * client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_SECTION *server_cs, size_t extra)
Allocate a new client from a config section.
void modules_init(char const *lib_dir)
Perform global initialisation for modules.
fr_log_dst_t dst
Log destination.
int fd
File descriptor to write messages to.
bool print_level
sometimes we don't want log levels printed
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
int fr_thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el)
Instantiate thread-specific data for modules, virtual servers, xlats, unlang, and TLS.
int fr_time_start(void)
Initialize the local time.
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
int fr_openssl_version_consistent(void)
static char const * receipt_file
static fr_event_list_t * el
static void _request_yield(request_t *request, void *uctx)
unsigned int count
How many connections to run.
static void _request_done_external(request_t *request, UNUSED rlm_rcode_t rcode, UNUSED void *uctx)
int main(int argc, char *argv[])
static void _tls_runnable(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Drain the runnable heap once per pass of the event loop.
unit_test_tls_conf_t conf
Parsed "unit_test_tls" section.
static void _request_resume(request_t *request, UNUSED void *uctx)
SSL_CTX * ssl_ctx
Context built from the "tls" section.
static void tls_request_finished(void *uctx, fr_tls_connection_t *conn)
Stop the event loop, recording why.
bool alert
Reject the peer with a TLS alert, see -A.
uint16_t port
Port of the listening socket, and the default port for -s.
static void _request_runnable(request_t *request, void *uctx)
static fr_client_t * tls_client_alloc(TALLOC_CTX *ctx, fr_ipaddr_t const *ipaddr)
Build an internal client.
static void _request_done_internal(request_t *request, UNUSED rlm_rcode_t rcode, UNUSED void *uctx)
int fd
Accepted or connected socket.
fr_event_list_t * el
Event list everything runs on.
static bool _request_scheduled(request_t const *request, UNUSED void *uctx)
static void _tls_connection_read(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
A record arrived on the connection, so hand the record to the connection.
static fr_dict_t const * dict_freeradius
static fr_dict_t const * dict_tls
static void tls_request_failed(unit_test_tls_t *utt)
Record a failure this program cannot recover from, and stop.
static void tls_runnable_insert(unit_test_tls_t *utt, request_t *request)
Schedule a request, once.
static void _request_detach(request_t *request, UNUSED void *uctx)
int yielded
How many requests are currently yielded.
fr_tls_connection_t * conn
State of the connection being run.
static void _tls_connection_start(fr_event_list_t *el, void *uctx)
Add the connection to the event loop, and get it moving.
static int tls_connection_write(void *uctx, fr_tls_connection_t *conn)
Write whatever OpenSSL has produced out to the connection.
bool require_client_certificate
Whether the client has to present a certificate.
fr_ipaddr_t ipaddr
Address of the listening socket. Server mode only.
fr_ipaddr_t server_ipaddr
Server named by -s.
static int tls_socket_connect(unit_test_tls_t *utt)
Connect to the server named by -s.
fr_dict_autoload_t unit_test_tls_dict[]
bool reject
Reject the session once the handshake succeeds, see -R.
char const * radiusd_version
unlang_interpret_t * intp
Interpreter for the connection.
static void _tls_connection_error(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int fd_errno, void *uctx)
The connection failed at the socket level.
fr_event_fd_t * ef
Read event for fd.
fr_heap_t * runnable
Requests the interpreter has marked runnable.
#define EXIT_WITH_FAILURE
static int tls_socket_open(unit_test_tls_t *utt)
Open the listening socket described by the "unit_test_tls" section.
int sockfd
Listening socket.
static request_t * tls_request_alloc(TALLOC_CTX *ctx, int fd)
Build the request the handshake runs under.
unsigned int connections
How many connections have been run so far.
static void _request_done_detached(request_t *request, UNUSED rlm_rcode_t rcode, UNUSED void *uctx)
bool done
Set once the connection has a result.
static const conf_parser_t unit_test_tls_config[]
static void _request_init_internal(request_t *request, void *uctx)
An internal request created by the interpreter has to run on ours.
static int tls_connection_run(unit_test_tls_t *utt)
Run one connection from the first byte to the last.
uint16_t server_port
Port from -s, or from the configuration.
The "unit_test_tls" section.
State of the test program.
#define FR_DICTIONARY_FILE
#define FR_DICTIONARY_INTERNAL_DIR
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
#define fr_strerror_const(_msg)
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
#define RADIUSD_VERSION_BUILD(_x)
Create a version string for a utility in the suite of FreeRADIUS utilities.
#define RADIUSD_MAGIC_NUMBER
#define fr_box_ipaddr(_val)
fr_dict_t const * virtual_server_dict_by_name(char const *virtual_server)
Return the namespace for the named virtual server.
virtual_server_t const * virtual_server_find(char const *name)
Return virtual server matching the specified name.
int virtual_servers_init(void)
Performs global initialisation for the virtual server code.
int virtual_servers_free(void)