Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_network_connect_abort.c

Interrupt an in-progress connect with netw_set_connect_abort_cb.

Interrupt an in-progress connect with netw_set_connect_abort_cb. A connect to an unresponsive host (a dropped SYN) otherwise blocks until the connect timeout. Registering a connect-abort callback makes the connect wait wake every NETW_CONNECT_ABORT_POLL_MS to poll it, so returning non-zero from the callback aborts the attempt at once. This example dials a TEST-NET-1 (RFC 5737, 192.0.2.0/24, not routed) address, which is guaranteed to have no listener, with a long connect timeout and a callback that asks to abort: the connect returns promptly rather than after the timeout.

Author
Castagnier Mickael
Version
1.0
Date
19/07/2026
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "nilorea/n_log.h"
#include "nilorea/n_time.h"
#define BLACKHOLE_HOST "192.0.2.1"
#define BLACKHOLE_PORT "80"
#define LONG_CONNECT_TIMEOUT_MS 20000
#define ABORT_MAX_MS 3000
static int g_polls = 0;
static int abort_now(void* ctx) {
(void)ctx;
return 1;
}
int main(void) {
int fails = 0;
/* 1) With an abort callback registered, a connect to an unresponsive host
returns quickly instead of blocking for the whole connect timeout. */
NETWORK* netw = NULL;
N_TIME timer;
start_HiTimer(&timer);
time_t elapsed_us = get_usec(&timer);
long elapsed_ms = (long)(elapsed_us / 1000);
n_log(LOG_INFO, "aborted connect: rc=%d elapsed=%ldms polls=%d", rc, elapsed_ms, g_polls);
if (rc != FALSE) {
n_log(LOG_ERR, "FAIL: connect to %s should not succeed", BLACKHOLE_HOST);
fails++;
}
if (elapsed_ms >= ABORT_MAX_MS) {
n_log(LOG_ERR, "FAIL: aborted connect took %ldms, expected < %dms", elapsed_ms, ABORT_MAX_MS);
fails++;
}
if (g_polls == 0) {
n_log(LOG_ERR, "FAIL: abort callback was never polled");
fails++;
}
if (netw)
/* 2) Removing the callback restores the default: connect blocks up to its
(here deliberately short) timeout and then fails. Kept short so the
example stays fast; only the return value is asserted, so an environment
that fast-fails an unroutable address does not turn this into a flake. */
netw = NULL;
g_polls = 0;
start_HiTimer(&timer);
elapsed_ms = (long)(get_usec(&timer) / 1000);
n_log(LOG_INFO, "no-callback connect: rc=%d elapsed=%ldms polls=%d", rc, elapsed_ms, g_polls);
if (rc != FALSE) {
n_log(LOG_ERR, "FAIL: connect to %s should not succeed", BLACKHOLE_HOST);
fails++;
}
if (g_polls != 0) {
n_log(LOG_ERR, "FAIL: callback polled after being removed");
fails++;
}
if (netw)
if (fails == 0)
n_log(LOG_INFO, "ex_network_connect_abort: all checks passed");
else
n_log(LOG_ERR, "ex_network_connect_abort: %d check(s) FAILED", fails);
return fails ? 1 : 0;
}
int main(void)
NETWORK * netw
Network for server mode, accepting incomming.
Definition ex_network.c:39
#define ABORT_MAX_MS
An aborted connect must return in well under the connect budget.
static int abort_now(void *ctx)
Connect-abort callback that always asks to abort, counting its polls.
static int g_polls
Count of times the abort callback was polled (proves it ran).
#define BLACKHOLE_PORT
Blackhole port (any).
#define LONG_CONNECT_TIMEOUT_MS
Long connect budget so an un-aborted attempt would clearly out-last an aborted one.
#define BLACKHOLE_HOST
Blackhole target: RFC 5737 documentation range, never has a listener.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_INFO
informational
Definition n_log.h:82
int start_HiTimer(N_TIME *timer)
Initialize or restart from zero any N_TIME HiTimer.
Definition n_time.c:85
time_t get_usec(N_TIME *timer)
Poll any N_TIME HiTimer, returning usec, and moving currentTime to startTime.
Definition n_time.c:107
Timing Structure.
Definition n_time.h:49
#define NETWORK_IPV4
Flag to force IPV4
Definition n_network.h:50
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
Definition n_network.c:2662
int netw_connect_to(NETWORK **netw, char *host, char *port, int ip_version, int connect_timeout_ms)
Connect a NETWORK with a bounded connection-establishment time.
Definition n_network.c:2373
void netw_set_connect_abort_cb(int(*cb)(void *ctx), void *ctx)
Register a process-wide callback polled while a connect is in progress.
Definition n_network.c:2172
Structure of a NETWORK.
Definition n_network.h:309
Generic log system.
Network Engine.
Timing utilities.