mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2024-09-21 10:27:19 +00:00
listen-netns: fix worker case for DTLS
while using udp, we later open a file descriptor for the worker. With a listen netns config, I overlooked this case which oblige me to move the struct containing the file descriptor in the main one. Then I can access them from each worker to make it possible to open the socket in the correct netns. I also need to keep the netns fd open during the whole life of the process. the issue was not visible on a tcp-only case, but while using udp you can see logs such as: main[user]: x.x.x.x:54024 bind UDP to 0.0.0.0:443: Cannot assign requested address worker[user]: x.x.x.x setting up DTLS-PSK connection main[user]: x.x.x.x:54024 bind UDP to 0.0.0.0:443: Cannot assign requested address update tests to reflects that: - instead of creating our own netns, use the one created in common.sh - we start server in ns1, but listen in ns2, and test client from ns3 (we don't want to listen in ns1 to test listen-ns) Signed-off-by: William Dauchy <w.dauchy@criteo.com>
This commit is contained in:
parent
8f6ff20f66
commit
80babceacf
32
src/main.c
32
src/main.c
@ -316,10 +316,10 @@ int _listen_unix_ports(void *pool, struct perm_cfg_st* config,
|
||||
*/
|
||||
static int
|
||||
listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
struct listen_list_st *list)
|
||||
struct listen_list_st *list,
|
||||
struct netns_fds *netns)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
struct netns_fds netns = {-1, -1};
|
||||
char portname[6];
|
||||
int ret;
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
@ -329,11 +329,6 @@ listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
list_head_init(&list->head);
|
||||
list->total = 0;
|
||||
|
||||
if (config->listen_netns_name && open_namespaces(&netns, config) < 0) {
|
||||
fprintf(stderr, "cannot init listen namespaces\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
/* Support for systemd socket-activatable service */
|
||||
if ((fds=sd_listen_fds(0)) > 0) {
|
||||
@ -427,7 +422,7 @@ listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _listen_ports(pool, config, res, list, &netns);
|
||||
ret = _listen_ports(pool, config, res, list, netns);
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (ret < 0) {
|
||||
@ -464,7 +459,7 @@ listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _listen_ports(pool, config, res, list, &netns);
|
||||
ret = _listen_ports(pool, config, res, list, netns);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -472,11 +467,6 @@ listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
if (config->listen_netns_name && close_namespaces(&netns) < 0) {
|
||||
fprintf(stderr, "cannot close listen namespaces\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -808,7 +798,7 @@ int sfd = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sfd = socket(listener->family, SOCK_DGRAM, listener->protocol);
|
||||
sfd = socket_netns(&s->netns, listener->family, SOCK_DGRAM, listener->protocol);
|
||||
if (sfd < 0) {
|
||||
e = errno;
|
||||
mslog(s, proc_to_send, LOG_ERR, "new UDP socket failed: %s",
|
||||
@ -1415,6 +1405,8 @@ int main(int argc, char** argv)
|
||||
s->stats.start_time = s->stats.last_reset = time(0);
|
||||
s->top_fd = -1;
|
||||
s->ctl_fd = -1;
|
||||
s->netns.default_fd = -1;
|
||||
s->netns.listen_fd = -1;
|
||||
|
||||
if (!hmac_init_key(sizeof(s->hmac_key), (uint8_t*)(s->hmac_key))) {
|
||||
fprintf(stderr, "unable to generate hmac key\n");
|
||||
@ -1476,8 +1468,12 @@ int main(int argc, char** argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (GETPCONFIG(s)->listen_netns_name && open_namespaces(&s->netns, GETPCONFIG(s)) < 0) {
|
||||
fprintf(stderr, "cannot init listen namespaces\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Listen to network ports */
|
||||
ret = listen_ports(s, GETPCONFIG(s), &s->listen_list);
|
||||
ret = listen_ports(s, GETPCONFIG(s), &s->listen_list, &s->netns);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot listen to specified ports\n");
|
||||
exit(1);
|
||||
@ -1670,6 +1666,10 @@ int main(int argc, char** argv)
|
||||
|
||||
snapshot_terminate(config_snapshot);
|
||||
|
||||
if (GETPCONFIG(s)->listen_netns_name && close_namespaces(&s->netns) < 0) {
|
||||
fprintf(stderr, "cannot close listen namespaces\n");
|
||||
exit(1);
|
||||
}
|
||||
clear_lists(s);
|
||||
clear_vhosts(s->vconfig);
|
||||
talloc_free(s->config_pool);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <ev.h>
|
||||
#include <hmac.h>
|
||||
#include "vhost.h"
|
||||
#include <namespace.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
# include <limits.h>
|
||||
@ -295,6 +296,8 @@ typedef struct main_server_st {
|
||||
/* used as temporary buffer (currently by forward_udp_to_owner) */
|
||||
uint8_t msg_buffer[MAX_MSG_SIZE];
|
||||
|
||||
struct netns_fds netns;
|
||||
|
||||
#ifdef RLIMIT_NOFILE
|
||||
struct rlimit fd_limits_default_set;
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@ isolate-workers = @ISOLATE_WORKERS@
|
||||
#banner = "Welcome"
|
||||
|
||||
# Use listen-host to limit to specific IPs or to the IPs of a provided hostname.
|
||||
#listen-host = @ADDRESS@
|
||||
listen-host = @ADDRESS@
|
||||
|
||||
listen-netns = @LISTEN_NS@
|
||||
|
||||
@ -171,7 +171,7 @@ ping-leases = false
|
||||
# Leave empty to assign the default MTU of the device
|
||||
# mtu =
|
||||
|
||||
route = 192.168.1.0/255.255.255.0
|
||||
#route = 192.168.1.0/255.255.255.0
|
||||
#route = 192.168.5.0/255.255.255.0
|
||||
|
||||
#
|
||||
|
@ -15,31 +15,37 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# we start server in ns1, but listen in ns2, and test client from ns3
|
||||
|
||||
SERV="${SERV:-../src/ocserv}"
|
||||
PIDFILE=ocserv-pid.$$.tmp
|
||||
CLIPID=oc-pid.$$.tmp
|
||||
srcdir=${srcdir:-.}
|
||||
LISTEN_NS="ocserv-listen-ns-tmp-$$"
|
||||
OUTFILE=lsof.$$.tmp
|
||||
OUTFILE=ss.$$.tmp
|
||||
SS=$(which ss)
|
||||
|
||||
ADDRESS=10.213.2.1
|
||||
ADDRESS2=10.213.2.2
|
||||
CLI_ADDRESS=10.213.1.1
|
||||
CLI_ADDRESS2=10.213.1.2
|
||||
VPNNET=172.17.215.0/24
|
||||
VPNADDR=172.17.215.1
|
||||
|
||||
function finish {
|
||||
set +e
|
||||
echo " * Cleaning up..."
|
||||
test -f "${CLIPID}" && kill $(cat ${CLIPID}) >/dev/null 2>&1
|
||||
test -n "${CLIPID}" && rm -f ${CLIPID} >/dev/null 2>&1
|
||||
test -n "${PID}" && kill ${PID} >/dev/null 2>&1
|
||||
test -n "${PIDFILE}" && rm -f ${PIDFILE} >/dev/null 2>&1
|
||||
test -n "${CONFIG}" && rm -f ${CONFIG} >/dev/null 2>&1
|
||||
test -n "${LISTEN_NS}" && ${IP} netns delete ${LISTEN_NS} >/dev/null 2>&1
|
||||
test -n "${OUTFILE}" && rm -f ${OUTFILE} >/dev/null 2>&1
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
. `dirname $0`/common.sh
|
||||
. `dirname $0`/ns.sh
|
||||
LISTEN_NS=$NSNAME2
|
||||
|
||||
eval "${GETPORT}"
|
||||
|
||||
@ -48,21 +54,71 @@ if test "$VERBOSE" = 1;then
|
||||
DEBUG="-d 3"
|
||||
fi
|
||||
|
||||
echo "Seting up listen namespace"
|
||||
${IP} netns add ${LISTEN_NS}
|
||||
|
||||
${CMDNS2} ${SERV} -p ${PIDFILE} -f -c ${CONFIG} ${DEBUG} & PID=$!
|
||||
${CMDNS1} ${SERV} -p ${PIDFILE} -f -c ${CONFIG} ${DEBUG} & PID=$!
|
||||
|
||||
sleep 5
|
||||
|
||||
${IP} netns exec ${LISTEN_NS} ${SS} -tulwn>${OUTFILE}
|
||||
grep "LISTEN" ${OUTFILE}
|
||||
echo "server: check listen tcp"
|
||||
${SS} -N ${LISTEN_NS} -nt -o state listening sport = :${PORT} src ${ADDRESS} > ${OUTFILE}
|
||||
grep -E "0[ ]+[0-9]+[ ]+${ADDRESS}:${PORT}[ ]+.*?:\*" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "ocserv is not listening in the correct namespace!"
|
||||
echo "server: check listen tcp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kill $PID
|
||||
echo "server: check listen udp"
|
||||
${SS} -N ${LISTEN_NS} -nu -o state unconnected sport = :${PORT} src ${ADDRESS} > ${OUTFILE}
|
||||
grep -E "0[ ]+0[ ]+${ADDRESS}:${PORT}[ ]+.*?:\*" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "server: check listen udp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " connecting to server"
|
||||
(echo "test" | ${CMDNS3} $OPENCONNECT $ADDRESS:$PORT -u "test" --servercert=d66b507ae074d03b02eafca40d35f87dd81049d3 --pid-file=${CLIPID} -b) ||
|
||||
fail $PID "could not connect to server"
|
||||
sleep 5
|
||||
|
||||
echo "server: check estab tcp"
|
||||
${SS} -N ${LISTEN_NS} -nt -o state established sport = :${PORT} src ${ADDRESS} dst ${CLI_ADDRESS2} > ${OUTFILE}
|
||||
grep -E "0[ ]+0[ ]+${ADDRESS}:${PORT}[ ]+${CLI_ADDRESS2}:[0-9]+" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "server: check estab tcp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "server: check estab udp"
|
||||
${SS} -N ${LISTEN_NS} -nu -o state established sport = :${PORT} src ${ADDRESS} dst ${CLI_ADDRESS2} > ${OUTFILE}
|
||||
grep -E "0[ ]+0[ ]+${ADDRESS}:${PORT}[ ]+${CLI_ADDRESS2}:[0-9]+" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "server: check estab udp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "client: check estab tcp"
|
||||
${SS} -N ${NSNAME3} -nt -o state established dport = :${PORT} src ${CLI_ADDRESS2} dst ${ADDRESS} > ${OUTFILE}
|
||||
grep -E "0[ ]+0[ ]+${CLI_ADDRESS2}:[0-9]+[ ]+${ADDRESS}:${PORT}" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "client: check estab tcp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "client: check estab udp"
|
||||
${SS} -N ${NSNAME3} -nu -o state established dport = :${PORT} src ${CLI_ADDRESS2} dst ${ADDRESS} > ${OUTFILE}
|
||||
grep -E "0[ ]+0[ ]+${CLI_ADDRESS2}:[0-9]+[ ]+${ADDRESS}:${PORT}" ${OUTFILE}
|
||||
if test $? != 0; then
|
||||
echo "client: check estab udp failed"
|
||||
cat ${OUTFILE}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kill $(cat ${CLIPID})
|
||||
kill ${PID}
|
||||
wait
|
||||
|
||||
exit 0
|
||||
|
Loading…
Reference in New Issue
Block a user