diff --git a/man/iodine.8 b/man/iodine.8 index b58890b..7146dd3 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -21,6 +21,8 @@ iodine, iodined \- tunnel IPv4 over DNS .I fragsize .B ] [-z .I context +.B ] [-F +.I pidfile .B ] .B [ .I nameserver @@ -51,6 +53,8 @@ iodine, iodined \- tunnel IPv4 over DNS .I password .B ] [-z .I context +.B ] [-F +.I pidfile .B ] .I tunnel_ip .B [ @@ -96,6 +100,9 @@ will be used as input. Only the first 32 characters will be used. .TP .B -z context Apply SELinux 'context' after initialization. +.TP +.B -F pidfile +Create 'pidfile' and write process id in it. .SS Client Options: .TP .B -m fragsize diff --git a/src/common.c b/src/common.c index ba87a89..a4ef691 100644 --- a/src/common.c +++ b/src/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef WINDOWS32 #include @@ -39,6 +40,7 @@ #include #include #include +#include #endif #ifdef HAVE_SETCON @@ -182,6 +184,24 @@ do_setcon(char *context) #endif } +void +do_pidfile(char *pidfile) +{ +#ifndef WINDOWS32 + FILE *file; + + if ((file = fopen(pidfile, "w")) == NULL) { + syslog(LOG_ERR, "Cannot write pidfile to %s, exiting", pidfile); + err(1, "do_pidfile: Can not write pidfile to %s", pidfile); + } else { + fprintf(file, "%d\n", (int)getpid()); + fclose(file); + } +#else + fprintf(stderr, "Windows version does not support pid file\n"); +#endif +} + void do_detach() { diff --git a/src/common.h b/src/common.h index cc977d2..3570058 100644 --- a/src/common.h +++ b/src/common.h @@ -104,6 +104,7 @@ void close_dns(int); void do_chroot(char *); void do_setcon(char *); void do_detach(); +void do_pidfile(char *); void read_password(char*, size_t); diff --git a/src/iodine.c b/src/iodine.c index 036b7d0..5888535 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -1158,7 +1158,8 @@ usage() { extern char *__progname; fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " - "[-P password] [-m maxfragsize] [-z context] [nameserver] topdomain\n", __progname); + "[-P password] [-m maxfragsize] [-z context] [-F pidfile] " + "[nameserver] topdomain\n", __progname); exit(2); } @@ -1168,7 +1169,8 @@ help() { fprintf(stderr, "iodine IP over DNS tunneling client\n"); fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] " - "[-P password] [-m maxfragsize] [-z context] [nameserver] topdomain\n", __progname); + "[-P password] [-m maxfragsize] [-z context] [-F pidfile] " + "[nameserver] topdomain\n", __progname); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); fprintf(stderr, " -f to keep running in foreground\n"); @@ -1178,6 +1180,7 @@ help() { fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n"); fprintf(stderr, " -m maxfragsize, to limit size of downstream packets\n"); fprintf(stderr, " -z context, to apply specified SELinux context after initialization\n"); + fprintf(stderr, " -F pidfile to write pid to a file\n"); fprintf(stderr, "nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n"); fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n"); @@ -1208,6 +1211,7 @@ main(int argc, char **argv) char *newroot; char *context; char *device; + char *pidfile; int choice; int tun_fd; int dns_fd; @@ -1227,6 +1231,7 @@ main(int argc, char **argv) context = NULL; device = NULL; chunkid = 0; + pidfile = NULL; outpkt.seqno = 0; inpkt.len = 0; @@ -1256,7 +1261,7 @@ main(int argc, char **argv) __progname++; #endif - while ((choice = getopt(argc, argv, "vfhru:t:d:P:m:")) != -1) { + while ((choice = getopt(argc, argv, "vfhru:t:d:P:m:F:")) != -1) { switch(choice) { case 'v': version(); @@ -1294,6 +1299,9 @@ main(int argc, char **argv) case 'z': context = optarg; break; + case 'F': + pidfile = optarg; + break; default: usage(); /* NOTREACHED */ @@ -1382,6 +1390,9 @@ main(int argc, char **argv) if (foreground == 0) do_detach(); + + if (pidfile != NULL) + do_pidfile(pidfile); if (newroot != NULL) do_chroot(newroot); @@ -1400,7 +1411,7 @@ main(int argc, char **argv) if (context != NULL) do_setcon(context); - + downstream_seqno = 0; downstream_fragment = 0; down_ack_seqno = 0; diff --git a/src/iodined.c b/src/iodined.c index 5028c84..8e3b9d7 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -1068,8 +1068,9 @@ usage() { fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] [-z context] " - "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip[/netmask] topdomain\n", __progname); + "[-l ip address to listen on] [-p port] [-n external ip] " + "[-b dnsport] [-P password] [-F pidfile] " + "tunnel_ip[/netmask] topdomain\n", __progname); exit(2); } @@ -1080,8 +1081,8 @@ help() { fprintf(stderr, "iodine IP over DNS tunneling server\n"); fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] [-z context] " - "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]" - " tunnel_ip[/netmask] topdomain\n", __progname); + "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password] " + "[-F pidfile] tunnel_ip[/netmask] topdomain\n", __progname); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); fprintf(stderr, " -c to disable check of client IP/port on each request\n"); @@ -1100,6 +1101,7 @@ help() { fprintf(stderr, " -n ip to respond with to NS queries\n"); fprintf(stderr, " -b port to forward normal DNS queries to (on localhost)\n"); fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n"); + fprintf(stderr, " -F pidfile to write pid to a file\n"); fprintf(stderr, "tunnel_ip is the IP number of the local tunnel interface.\n"); fprintf(stderr, " /netmask sets the size of the tunnel network.\n"); fprintf(stderr, "topdomain is the FQDN that is delegated to this server.\n"); @@ -1128,6 +1130,7 @@ main(int argc, char **argv) char *newroot; char *context; char *device; + char *pidfile; int dnsd_fd; int tun_fd; @@ -1161,6 +1164,7 @@ main(int argc, char **argv) skipipconfig = 0; debug = 0; netmask = 27; + pidfile = NULL; b32 = get_base32_encoder(); @@ -1182,7 +1186,7 @@ main(int argc, char **argv) srand(time(NULL)); fw_query_init(); - while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:z:")) != -1) { + while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:z:F:")) != -1) { switch(choice) { case 'v': version(); @@ -1227,6 +1231,9 @@ main(int argc, char **argv) bind_enable = 1; bind_port = atoi(optarg); break; + case 'F': + pidfile = optarg; + break; case 'P': strncpy(password, optarg, sizeof(password)); password[sizeof(password)-1] = 0; @@ -1374,6 +1381,9 @@ main(int argc, char **argv) if (foreground == 0) do_detach(); + if (pidfile != NULL) + do_pidfile(pidfile); + if (newroot != NULL) do_chroot(newroot); @@ -1392,9 +1402,6 @@ main(int argc, char **argv) if (context != NULL) do_setcon(context); -#ifndef WINDOWS32 - openlog(__progname, LOG_NOWAIT, LOG_DAEMON); -#endif syslog(LOG_INFO, "started, listening on port %d", port); tunnel(tun_fd, dnsd_fd, bind_fd);