From c9c47e9a6ba56a927635a482b3d48e010e5dfcbd Mon Sep 17 00:00:00 2001 From: hev Date: Sat, 18 May 2024 23:03:20 +0800 Subject: [PATCH] NATMap: Add fwmark. --- README.md | 1 + src/hev-conf.c | 13 ++++++++++++- src/hev-conf.h | 9 +++++++++ src/hev-sock.c | 28 +++++++++++++++++++++++++--- src/hev-sock.h | 9 ++++++--- src/hev-stun.c | 5 ++++- src/hev-tnsk.c | 4 +++- src/hev-unsk.c | 4 +++- 8 files changed, 63 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 041ce6e..68447a8 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Options: -s [:port] domain name or address of STUN server -h [:port] domain name or address of HTTP server -e script path for notify mapped address + -f fwmark value Bind options: -b port number for binding diff --git a/src/hev-conf.c b/src/hev-conf.c index dbb998e..d9fa58d 100644 --- a/src/hev-conf.c +++ b/src/hev-conf.c @@ -21,6 +21,7 @@ static int type = AF_UNSPEC; static int keep; static int dmon; static int tmsec; +static unsigned int mark; static char mport[16]; static char sport[16] = "3478"; @@ -52,6 +53,7 @@ hev_conf_help (void) " -s [:port] domain name or address of STUN server\n" " -h [:port] domain name or address of HTTP server\n" " -e script path for notify mapped address\n" + " -f fwmark value\n" "\n" "Bind options:\n" " -b port number for binding\n" @@ -69,7 +71,7 @@ hev_conf_init (int argc, char *argv[]) { int opt; - while ((opt = getopt (argc, argv, "46udk:s:h:e:b:T:t:p:i:")) != -1) { + while ((opt = getopt (argc, argv, "46udk:s:h:e:f:b:T:t:p:i:")) != -1) { switch (opt) { case '4': type = AF_INET; @@ -95,6 +97,9 @@ hev_conf_init (int argc, char *argv[]) case 'e': path = optarg; break; + case 'f': + mark = strtoul (optarg, NULL, 16); + break; case 'b': bport = optarg; break; @@ -181,6 +186,12 @@ hev_conf_path (void) return path; } +unsigned int +hev_conf_mark (void) +{ + return mark; +} + const char * hev_conf_baddr (void) { diff --git a/src/hev-conf.h b/src/hev-conf.h index 9ce41f3..09c03b2 100644 --- a/src/hev-conf.h +++ b/src/hev-conf.h @@ -84,6 +84,15 @@ const char *hev_conf_http (void); */ const char *hev_conf_path (void); +/** + * hev_conf_mark: + * + * Get the fwmark value. + * + * Returns: returns string. + */ +unsigned int hev_conf_mark (void); + /** * hev_conf_baddr: * diff --git a/src/hev-sock.c b/src/hev-sock.c index 84e8b78..bbf7eb0 100644 --- a/src/hev-sock.c +++ b/src/hev-sock.c @@ -104,9 +104,21 @@ bind_iface (int fd, int family, const char *iface) return -1; } +static int +bind_fwmark (int fd, unsigned int mark) +{ +#if defined(__linux__) + return setsockopt (fd, SOL_SOCKET, SO_MARK, &mark, sizeof (mark)); +#elif defined(__FreeBSD__) + return setsockopt (fd, SOL_SOCKET, SO_USER_COOKIE, &mark, sizeof (mark)); +#endif + return 0; +} + int hev_sock_client_tcp (int family, const char *saddr, const char *sport, - const char *daddr, const char *dport, const char *iface) + const char *daddr, const char *dport, const char *iface, + unsigned int mark) { struct addrinfo *sai; struct addrinfo *dai; @@ -136,6 +148,9 @@ hev_sock_client_tcp (int family, const char *saddr, const char *sport, } res = bind_iface (fd, sai->ai_family, iface); + if (mark) { + res |= bind_fwmark (fd, mark); + } if (res < 0) { LOG (E); freeaddrinfo (sai); @@ -181,7 +196,7 @@ hev_sock_client_tcp (int family, const char *saddr, const char *sport, int hev_sock_client_udp (int family, const char *saddr, const char *sport, - const char *iface) + const char *iface, unsigned int mark) { struct addrinfo *sai; int res; @@ -201,6 +216,9 @@ hev_sock_client_udp (int family, const char *saddr, const char *sport, } res = bind_iface (fd, sai->ai_family, iface); + if (mark) { + res |= bind_fwmark (fd, mark); + } if (res < 0) { LOG (E); freeaddrinfo (sai); @@ -226,7 +244,8 @@ hev_sock_client_udp (int family, const char *saddr, const char *sport, int hev_sock_client_stun (int fd, int type, const char *daddr, const char *dport, - const char *iface, unsigned int baddr[4], int *bport) + const char *iface, unsigned int mark, + unsigned int baddr[4], int *bport) { struct addrinfo sai; struct addrinfo *dai; @@ -258,6 +277,9 @@ hev_sock_client_stun (int fd, int type, const char *daddr, const char *dport, } res = bind_iface (fd, sai.ai_family, iface); + if (mark) { + res |= bind_fwmark (fd, mark); + } if (res < 0) { LOG (E); freeaddrinfo (dai); diff --git a/src/hev-sock.h b/src/hev-sock.h index 7f07b70..8c3b91b 100644 --- a/src/hev-sock.h +++ b/src/hev-sock.h @@ -18,6 +18,7 @@ * @daddr: destination addr * @dport: destination port * @iface: network interface + * @mark: fwmark * * Create a socket for TCP client. * @@ -25,7 +26,7 @@ */ int hev_sock_client_tcp (int family, const char *saddr, const char *sport, const char *daddr, const char *dport, - const char *iface); + const char *iface, unsigned int mark); /** * hev_sock_client_udp: @@ -33,13 +34,14 @@ int hev_sock_client_tcp (int family, const char *saddr, const char *sport, * @saddr: source addr * @sport: source port * @iface: network interface + * @mark: fwmark * * Create a socket for UDP client. * * Returns: returns file descriptor on successful, otherwise returns -1. */ int hev_sock_client_udp (int family, const char *saddr, const char *sport, - const char *iface); + const char *iface, unsigned int mark); /** * hev_sock_client_stun: @@ -48,6 +50,7 @@ int hev_sock_client_udp (int family, const char *saddr, const char *sport, * @daddr: destination addr * @dport: destination port * @iface: network interface + * @mark: fwmark * @baddr: [out] bound addr * @bport: [out] bound port * @@ -57,7 +60,7 @@ int hev_sock_client_udp (int family, const char *saddr, const char *sport, */ int hev_sock_client_stun (int fd, int type, const char *daddr, const char *dport, const char *iface, - unsigned int baddr[4], int *bport); + unsigned int mark, unsigned int baddr[4], int *bport); /** * hev_sock_client_pfwd: diff --git a/src/hev-stun.c b/src/hev-stun.c index 55b22e2..52cc52d 100644 --- a/src/hev-stun.c +++ b/src/hev-stun.c @@ -284,6 +284,7 @@ task_entry (void *data) const char *iface; const char *stun; const char *sport; + unsigned int mark; int bport; int mode; int tfd; @@ -295,8 +296,10 @@ task_entry (void *data) stun = hev_conf_stun (); sport = hev_conf_sport (); iface = hev_conf_iface (); + mark = hev_conf_mark (); - fd = hev_sock_client_stun (tfd, mode, stun, sport, iface, baddr, &bport); + fd = hev_sock_client_stun (tfd, mode, stun, sport, iface, mark, baddr, + &bport); close (tfd); if (fd < 0) { LOGV (E, "%s", "Start STUN service failed."); diff --git a/src/hev-tnsk.c b/src/hev-tnsk.c index 9f388f7..32b673f 100644 --- a/src/hev-tnsk.c +++ b/src/hev-tnsk.c @@ -90,6 +90,7 @@ tnsk_run (void) const char *port; const char *hport; const char *iface; + unsigned int mark; int type; type = hev_conf_type (); @@ -99,8 +100,9 @@ tnsk_run (void) port = hev_conf_bport (); hport = hev_conf_hport (); iface = hev_conf_iface (); + mark = hev_conf_mark (); - fd = hev_sock_client_tcp (type, addr, port, http, hport, iface); + fd = hev_sock_client_tcp (type, addr, port, http, hport, iface, mark); if (fd < 0) { LOGV (E, "%s", "Start TCP keep-alive service failed."); return; diff --git a/src/hev-unsk.c b/src/hev-unsk.c index 04fa9ab..be81f6e 100644 --- a/src/hev-unsk.c +++ b/src/hev-unsk.c @@ -57,6 +57,7 @@ unsk_run (void) const char *addr; const char *port; const char *iface; + unsigned int mark; int type; type = hev_conf_type (); @@ -64,9 +65,10 @@ unsk_run (void) addr = hev_conf_baddr (); port = hev_conf_bport (); iface = hev_conf_iface (); + mark = hev_conf_mark (); timeout = hev_conf_keep (); - fd = hev_sock_client_udp (type, addr, port, iface); + fd = hev_sock_client_udp (type, addr, port, iface, mark); if (fd < 0) { LOGV (E, "%s", "Start UDP keep-alive service failed."); return;