From e639def7c8ad8508c2dd3569a2ed2434831bce68 Mon Sep 17 00:00:00 2001 From: zfl9 Date: Sat, 31 Aug 2019 14:52:06 +0800 Subject: update dns2tcp.c --- dns2tcp.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/dns2tcp.c b/dns2tcp.c index 14d46cb..fb60d63 100644 --- a/dns2tcp.c +++ b/dns2tcp.c @@ -10,7 +10,16 @@ #include #undef _GNU_SOURCE -static bool g_verbose = false; +#define DNS2TCP_VERSION "dns2tcp v1.0" + +static bool g_verbose = false; +static uv_loop_t *g_evloop = NULL; +static char g_listen_ipstr[IP6STRLEN] = {0}; +static portno_t g_listen_portno = 0; +static skaddr6_t g_listen_skaddr = {0}; +static char g_remote_ipstr[IP6STRLEN] = {0}; +static portno_t g_remote_portno = 0; +static skaddr6_t g_remote_skaddr = {0}; static void print_command_help(void) { printf("usage: dns2tcp <-L LISTEN_ADDR> <-R REMOTE_ADDR> [-vVh]\n" @@ -23,30 +32,120 @@ static void print_command_help(void) { ); } +static void parse_address_opt(char *ip_port_str, bool is_listen_addr) { + const char *opt_name = is_listen_addr ? "listen" : "remote"; + + char *portstr = strchr(ip_port_str, '#'); + if (!portstr) { + printf("[parse_address_opt] %s port is not specified\n", opt_name); + goto PRINT_HELP_AND_EXIT; + } + if (portstr == ip_port_str) { + printf("[parse_address_opt] %s addr is not specified\n", opt_name); + goto PRINT_HELP_AND_EXIT; + } + + *portstr = 0; ++portstr; + if (strlen(portstr) + 1 > PORTSTRLEN) { + printf("[parse_address_opt] %s port is invalid: %s\n", opt_name, portstr); + goto PRINT_HELP_AND_EXIT; + } + portno_t portno = strtol(portstr, NULL, 10); + if (portno == 0) { + printf("[parse_address_opt] %s port is invalid: %s\n", opt_name, portstr); + goto PRINT_HELP_AND_EXIT; + } + + char *ipstr = ip_port_str; + if (strlen(ipstr) + 1 > IP6STRLEN) { + printf("[parse_address_opt] %s addr is invalid: %s\n", opt_name, ipstr); + goto PRINT_HELP_AND_EXIT; + } + int ipfamily = get_ipstr_family(ipstr); + if (ipfamily == -1) { + printf("[parse_address_opt] %s addr is invalid: %s\n", opt_name, ipstr); + goto PRINT_HELP_AND_EXIT; + } + + void *skaddr_ptr = is_listen_addr ? &g_listen_skaddr : &g_remote_skaddr; + if (ipfamily == AF_INET) { + build_ipv4_addr(skaddr_ptr, ipstr, portno); + } else { + build_ipv6_addr(skaddr_ptr, ipstr, portno); + } + + if (is_listen_addr) { + strcpy(g_listen_ipstr, ipstr); + g_listen_portno = portno; + } else { + strcpy(g_remote_ipstr, ipstr); + g_remote_portno = portno; + } + return; + +PRINT_HELP_AND_EXIT: + print_command_help(); + exit(1); +} + static void parse_command_args(int argc, char *argv[]) { + char *opt_listen_addr = NULL; + char *opt_remote_addr = NULL; + opterr = 0; int shortopt = -1; - char *bindaddr_optarg = NULL; - char *servaddr_optarg = NULL; - const char *optstr = ":L:R:vVh"; + const char *optstr = "L:R:vVh"; while ((shortopt = getopt(argc, argv, optstr)) != -1) { switch (shortopt) { case 'L': - bindaddr_optarg = optarg; + opt_listen_addr = optarg; break; case 'R': - servaddr_optarg = optarg; + opt_remote_addr = optarg; + break; case 'v': g_verbose = true; + break; + case 'V': + printf(DNS2TCP_VERSION"\n"); + exit(0); + case 'h': + print_command_help(); + exit(0); + case '?': + if (!strchr(optstr, optopt)) { + printf("[parse_command_args] unknown option '-%c'\n", optopt); + } else { + printf("[parse_command_args] missing optval '-%c'\n", optopt); + } + goto PRINT_HELP_AND_EXIT; } } + + if (!opt_listen_addr) { + printf("[parse_command_args] missing option: '-L'\n"); + goto PRINT_HELP_AND_EXIT; + } + if (!opt_remote_addr) { + printf("[parse_command_args] missing option: '-R'\n"); + goto PRINT_HELP_AND_EXIT; + } + + parse_address_opt(opt_listen_addr, true); + parse_address_opt(opt_remote_addr, false); return; + PRINT_HELP_AND_EXIT: print_command_help(); exit(1); } -int main() { - print_command_help(); +int main(int argc, char *argv[]) { + signal(SIGPIPE, SIG_IGN); + setvbuf(stdout, NULL, _IOLBF, 256); + parse_command_args(argc, argv); + + // TODO + return 0; } -- cgit v1.2.3