Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- skip ipv6 tests on old libslirp versions
- install openssl-devel on centos box
- use *hostfwd functions on old libslirp versions

Signed-off-by: fassl <[email protected]>
  • Loading branch information
pfandl committed Sep 11, 2021
1 parent 7dce49c commit 346fb19
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Vagrant.configure("2") do |config|
yum install -y \
autoconf automake make gcc gperf libtool \
git-core meson ninja-build \
glib2-devel libcap-devel \
glib2-devel libcap-devel openssl-devel \
git-core libtool iproute iputils iperf3 nmap jq
# TODO: install udhcpc (required by test-slirp4netns-dhcp.sh)
Expand Down
97 changes: 67 additions & 30 deletions api.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,22 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
free(fwd);
goto finish;
}
#if SLIRP_CONFIG_VERSION_MAX >= 3
int flags = (fwd->is_udp ? SLIRP_HOSTFWD_UDP : 0);
#endif

if (host_addr_s == NULL || host_addr_s[0] == '\0') {
host_addr_s = "0.0.0.0";
}
if (strcmp("0.0.0.0", host_addr_s) == 0 ||
strcmp("::", host_addr_s) == 0 ||
if (strcmp("0.0.0.0", host_addr_s) == 0 || strcmp("::", host_addr_s) == 0 ||
strcmp("::0", host_addr_s) == 0) {
fwd->is_ipv4 = 1;
fwd->is_ipv6 = ctx->cfg->enable_ipv6;
host_addr_s = "0.0.0.0";
} else {
if (strchr(host_addr_s, '.')) {
fwd->is_ipv4 = 1;
}
else if (strchr(host_addr_s, ':')) {
} else if (strchr(host_addr_s, ':')) {
if (!ctx->cfg->enable_ipv6) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
Expand Down Expand Up @@ -201,9 +201,11 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
fwd->guest.sin_port = htons(fwd->guest_port);
if (guest_addr_s == NULL || guest_addr_s[0] == '\0') {
fwd->guest.sin_addr = ctx->cfg->recommended_vguest;
} else if (inet_pton(AF_INET, guest_addr_s, &fwd->guest.sin_addr) != 1) {
const char *err = "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"bad arguments.guest_addr\"}}";
} else if (inet_pton(AF_INET, guest_addr_s, &fwd->guest.sin_addr) !=
1) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"bad arguments.guest_addr\"}}";
wrc = write(fd, err, strlen(err));
free(fwd);
goto finish;
Expand All @@ -216,28 +218,45 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
free(fwd);
goto finish;
}
if (slirp_add_hostxfwd(slirp,
(const struct sockaddr*)&fwd->host, sizeof(fwd->host),
(const struct sockaddr*)&fwd->guest, sizeof(fwd->guest), flags) < 0) {
#if SLIRP_CONFIG_VERSION_MAX >= 3
if (slirp_add_hostxfwd(slirp, (const struct sockaddr *)&fwd->host,
sizeof(fwd->host),
(const struct sockaddr *)&fwd->guest,
sizeof(fwd->guest), flags) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"slirp_add_hostxfwd failed\"}}";
wrc = write(fd, err, strlen(err));
free(fwd);
goto finish;
}
#else
if (slirp_add_hostfwd(slirp, fwd->is_udp, fwd->host.sin_addr,
fwd->host_port, fwd->guest.sin_addr,
fwd->guest_port) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"slirp_add_hostxfwd failed\"}}";
wrc = write(fd, err, strlen(err));
free(fwd);
goto finish;
}
#endif
}

#if SLIRP_CONFIG_VERSION_MAX >= 3
if (fwd->is_ipv6) {
fwd->host6.sin6_family = AF_INET6;
fwd->guest6.sin6_family = AF_INET6;
fwd->host6.sin6_port = htons(fwd->host_port);
fwd->guest6.sin6_port = htons(fwd->guest_port);
if (guest_addr_s == NULL || guest_addr_s[0] == '\0') {
fwd->guest6.sin6_addr = ctx->cfg->recommended_vguest6;
} else if (inet_pton(AF_INET6, guest_addr_s, &fwd->guest6.sin6_addr) != 1) {
const char *err = "{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"bad arguments.guest_addr\"}}";
} else if (inet_pton(AF_INET6, guest_addr_s, &fwd->guest6.sin6_addr) !=
1) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"bad arguments.guest_addr\"}}";
wrc = write(fd, err, strlen(err));
free(fwd);
goto finish;
Expand All @@ -254,9 +273,10 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
goto finish;
}
flags |= SLIRP_HOSTFWD_V6ONLY;
if (slirp_add_hostxfwd(slirp,
(const struct sockaddr*)&fwd->host6, sizeof(fwd->host6),
(const struct sockaddr*)&fwd->guest6, sizeof(fwd->guest6), flags) < 0) {
if (slirp_add_hostxfwd(slirp, (const struct sockaddr *)&fwd->host6,
sizeof(fwd->host6),
(const struct sockaddr *)&fwd->guest6,
sizeof(fwd->guest6), flags) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: add_hostfwd: "
"slirp_add_hostxfwd failed\"}}";
Expand All @@ -265,6 +285,7 @@ static int api_handle_req_add_hostfwd(Slirp *slirp, int fd, struct api_ctx *ctx,
goto finish;
}
}
#endif
fwd->id = ctx->hostfwds_nextid;
ctx->hostfwds_nextid++;
ctx->hostfwds = g_list_append(ctx->hostfwds, fwd);
Expand All @@ -288,25 +309,25 @@ static void api_handle_req_list_hostfwd_foreach(gpointer data,
char host_addr[INET_ADDRSTRLEN], guest_addr[INET_ADDRSTRLEN];
char host_addr6[INET6_ADDRSTRLEN], guest_addr6[INET6_ADDRSTRLEN];
if (fwd->is_ipv4) {
if (inet_ntop(AF_INET, &fwd->host.sin_addr, host_addr, sizeof(host_addr)) ==
NULL) {
if (inet_ntop(AF_INET, &fwd->host.sin_addr, host_addr,
sizeof(host_addr)) == NULL) {
perror("fatal: inet_ntop");
exit(EXIT_FAILURE);
}
if (inet_ntop(AF_INET, &fwd->guest.sin_addr, guest_addr, sizeof(guest_addr)) ==
NULL) {
if (inet_ntop(AF_INET, &fwd->guest.sin_addr, guest_addr,
sizeof(guest_addr)) == NULL) {
perror("fatal: inet_ntop");
exit(EXIT_FAILURE);
}
}
if (fwd->is_ipv6) {
if (inet_ntop(AF_INET6, &fwd->host6.sin6_addr, host_addr6, sizeof(host_addr6)) ==
NULL) {
if (inet_ntop(AF_INET6, &fwd->host6.sin6_addr, host_addr6,
sizeof(host_addr6)) == NULL) {
perror("fatal: inet_ntop");
exit(EXIT_FAILURE);
}
if (inet_ntop(AF_INET6, &fwd->guest6.sin6_addr, guest_addr6, sizeof(guest_addr6)) ==
NULL) {
if (inet_ntop(AF_INET6, &fwd->guest6.sin6_addr, guest_addr6,
sizeof(guest_addr6)) == NULL) {
perror("fatal: inet_ntop");
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -384,21 +405,37 @@ static int api_handle_req_remove_hostfwd(Slirp *slirp, int fd,
struct api_hostfwd *fwd = found->data;
const char *api_ok = "{\"return\":{}}";
if (fwd->is_ipv4) {
#if SLIRP_CONFIG_VERSION_MAX >= 3
if (slirp_remove_hostxfwd(slirp,
(const struct sockaddr*)&fwd->host, sizeof(fwd->host), 0) < 0) {
const char *err = "{\"error\":{\"desc\":\"bad request: "
"remove_hostfwd: slirp_remove_hostxfwd failed\"}}";
(const struct sockaddr *)&fwd->host,
sizeof(fwd->host), 0) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: "
"remove_hostfwd: slirp_remove_hostxfwd failed\"}}";
return write(fd, err, strlen(err));
}
#else
if (slirp_remove_hostfwd(slirp, fwd->is_udp, fwd->host.sin_addr,
fwd->host_port) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: "
"remove_hostfwd: slirp_remove_hostfwd failed\"}}";
return write(fd, err, strlen(err));
}
#endif
}
#if SLIRP_CONFIG_VERSION_MAX >= 3
if (fwd->is_ipv6) {
if (slirp_remove_hostxfwd(slirp,
(const struct sockaddr*)&fwd->host6, sizeof(fwd->host6), 0) < 0) {
const char *err = "{\"error\":{\"desc\":\"bad request: "
"remove_hostfwd: slirp_remove_hostxfwd failed\"}}";
(const struct sockaddr *)&fwd->host6,
sizeof(fwd->host6), 0) < 0) {
const char *err =
"{\"error\":{\"desc\":\"bad request: "
"remove_hostfwd: slirp_remove_hostxfwd failed\"}}";
return write(fd, err, strlen(err));
}
}
#endif
ctx->hostfwds = g_list_remove(ctx->hostfwds, fwd);
g_free(fwd);
wrc = write(fd, api_ok, strlen(api_ok));
Expand Down
43 changes: 23 additions & 20 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@ static const char *pseudo_random_global_id(const char *device)
return NULL;
}
close(rand);
}
else {
strncpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, sizeof(mac));
} else {
strncpy((char *)mac, (const char *)ifr.ifr_ifru.ifru_addr.sa_data,
sizeof(mac));
}

/* https://tools.ietf.org/html/rfc4193
Expand Down Expand Up @@ -988,9 +988,8 @@ static int parse_cidr6(struct in6_addr *network, struct in6_addr *netmask,
regmatch_t matches[5];
size_t nmatch = sizeof(matches) / sizeof(matches[0]);
const char *cidr_regex = "^((([a-fA-F0-9]{1,4}):){1,4}):/([0-9]{1,3})";
char snetwork[INET6_ADDRSTRLEN],
snetwork_end[INET6_ADDRSTRLEN],
sprefix[INET6_ADDRSTRLEN];
char snetwork[INET6_ADDRSTRLEN], snetwork_end[INET6_ADDRSTRLEN],
sprefix[INET6_ADDRSTRLEN];
int prefix;
const char *random;
rc = regcomp(&r, cidr_regex, REG_EXTENDED);
Expand All @@ -1015,7 +1014,7 @@ static int parse_cidr6(struct in6_addr *network, struct in6_addr *netmask,
fprintf(stderr, "invalid CIDR: %s\n", cidr);
goto finish;
}
strcat(snetwork, ":");
strncat(snetwork, ":", 2);
if (inet_pton(AF_INET6, snetwork, network) != 1) {
fprintf(stderr, "invalid network address: %s\n", snetwork);
rc = -1;
Expand All @@ -1029,8 +1028,8 @@ static int parse_cidr6(struct in6_addr *network, struct in6_addr *netmask,
goto finish;
}
if (prefix < NETWORK_PREFIX_MIN6 || prefix > NETWORK_PREFIX_MAX6) {
fprintf(stderr, "prefix length needs to be %d-%d\n", NETWORK_PREFIX_MIN6,
NETWORK_PREFIX_MAX6);
fprintf(stderr, "prefix length needs to be %d-%d\n",
NETWORK_PREFIX_MIN6, NETWORK_PREFIX_MAX6);
rc = -1;
goto finish;
}
Expand Down Expand Up @@ -1085,32 +1084,36 @@ static int slirp4netns_config_from_cidr6(struct slirp4netns_config *cfg,
return -1;
}

#define MAX(a,b) (((a)>(b))?(a):(b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

strncpy(tmp, net, sizeof(tmp));
strncat(tmp, DEFAULT_VHOST_OFFSET6,
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) - strlen(DEFAULT_VHOST_OFFSET6)));
strncat(
tmp, DEFAULT_VHOST_OFFSET6,
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) - strlen(DEFAULT_VHOST_OFFSET6)));
if (inet_pton(AF_INET6, tmp, &cfg->vhost6) != 1) {
return -1;
}

strncpy(tmp, net, sizeof(tmp));
strncat(tmp, DEFAULT_VDHCPSTART_OFFSET6,
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) - strlen(DEFAULT_VDHCPSTART_OFFSET6)));
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) -
strlen(DEFAULT_VDHCPSTART_OFFSET6)));
if (inet_pton(AF_INET6, tmp, &cfg->vdhcp_start6) != 1) {
return -1;
}

strncpy(tmp, net, sizeof(tmp));
strncat(tmp, DEFAULT_VNAMESERVER_OFFSET6,
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) - strlen(DEFAULT_VNAMESERVER_OFFSET6)));
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) -
strlen(DEFAULT_VNAMESERVER_OFFSET6)));
if (inet_pton(AF_INET6, tmp, &cfg->vnameserver6) != 1) {
return -1;
}

strncpy(tmp, net, sizeof(tmp));
strncat(tmp, DEFAULT_RECOMMENDED_VGUEST_OFFSET6,
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) - strlen(DEFAULT_RECOMMENDED_VGUEST_OFFSET6)));
MAX(0, INET6_ADDRSTRLEN - strlen(tmp) -
strlen(DEFAULT_RECOMMENDED_VGUEST_OFFSET6)));
if (inet_pton(AF_INET6, tmp, &cfg->recommended_vguest6) != 1) {
return -1;
}
Expand Down Expand Up @@ -1196,18 +1199,18 @@ static int slirp4netns_config_from_options(struct slirp4netns_config *cfg,
cfg->enable_seccomp = opt->enable_seccomp;

if (cfg->enable_ipv6) {
const char *cidr = opt->cidr6;
if (cidr == NULL) {
cidr = DEFAULT_CIDR6;
const char *cidr = opt->cidr6;
if (cidr == NULL) {
cidr = DEFAULT_CIDR6;
if (opt->ipv6_random) {
cidr = pseudo_random_global_id("tap0");
if (cidr == NULL) {
fprintf(stderr, "cannot create pseudo random global id\n");
rc = -1;
goto finish;
}
}
}
}
}
rc = slirp4netns_config_from_cidr6(cfg, cidr);
if (rc < 0) {
goto finish;
Expand Down
7 changes: 7 additions & 0 deletions tests/test-slirp4netns-hostfwd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ set -xeuo pipefail

. $(dirname $0)/common.sh

SLIRP_CONFIG_VERSION_MAX=$(slirp4netns -v | grep "SLIRP_CONFIG_VERSION_MAX: " | sed 's#SLIRP_CONFIG_VERSION_MAX: \(\)##')

if [ "${SLIRP_CONFIG_VERSION_MAX:-0}" -lt 3 ]; then
printf "forwarding test requires SLIRP_CONFIG_VERSION_MAX 3 or newer. Test skipped..."
exit "$TEST_EXIT_CODE_SKIP"
fi

host_port=8080
guest_port=1080
cidr=fd00:a1e1:1724:1a
Expand Down
5 changes: 5 additions & 0 deletions tests/test-slirp4netns-hostfwd4.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ set -xeuo pipefail

. $(dirname $0)/common.sh

if [ "${SLIRP_CONFIG_VERSION_MAX:-0}" -lt 3 ]; then
printf "forwarding test requires SLIRP_CONFIG_VERSION_MAX 3 or newer. Test skipped..."
exit "$TEST_EXIT_CODE_SKIP"
fi

host_port=8080
guest_port=1080

Expand Down
5 changes: 5 additions & 0 deletions tests/test-slirp4netns-hostfwd6.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ set -xeuo pipefail

. $(dirname $0)/common.sh

if [ "${SLIRP_CONFIG_VERSION_MAX:-0}" -lt 3 ]; then
printf "forwarding test requires SLIRP_CONFIG_VERSION_MAX 3 or newer. Test skipped..."
exit "$TEST_EXIT_CODE_SKIP"
fi

host_port=8080
guest_port=1080
cidr=fd00:a1e1:1724:1a
Expand Down
5 changes: 5 additions & 0 deletions tests/test-slirp4netns-ipv6.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ set -xeuo pipefail

. $(dirname $0)/common.sh

if [ "${SLIRP_CONFIG_VERSION_MAX:-0}" -lt 3 ]; then
printf "ipv6 test requires SLIRP_CONFIG_VERSION_MAX 3 or newer. Test skipped..."
exit "$TEST_EXIT_CODE_SKIP"
fi

host_port=8080
guest_port=80
cidr=fd00:a1e1:1724:1a
Expand Down

0 comments on commit 346fb19

Please sign in to comment.