server/: Eliminate the remaining address-family-specific knowledge.
[tripe] / server / tripe.c
index 1e6d406..d8a6cc1 100644 (file)
@@ -9,19 +9,18 @@
  *
  * This file is part of Trivial IP Encryption (TrIPE).
  *
- * TrIPE is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * TrIPE is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your
+ * option) any later version.
  *
- * TrIPE is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * TrIPE is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with TrIPE; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
  */
 
 /*----- Header files ------------------------------------------------------*/
@@ -120,11 +119,11 @@ int main(int argc, char *argv[])
   int csockmode = 0600;
   const char *dir = CONFIGDIR;
   const char *p;
-  unsigned port = TRIPE_PORT;
-  struct in_addr baddr = { INADDR_ANY };
+  const char *bindhost = 0, *bindsvc = STR(TRIPE_PORT);
+  struct addrinfo aihint = { 0 }, *ailist;
   unsigned f = 0;
   int i;
-  int selerr = 0;
+  int err, selerr = 0;
   unsigned af;
   struct timeval tv;
   uid_t u = -1;
@@ -142,6 +141,7 @@ int main(int argc, char *argv[])
   if ((p = getenv("TRIPESOCK")) != 0)
     csock = p;
   tun_default = tunnels[0];
+  aihint.ai_family = AF_INET;
 
   for (;;) {
     static const struct option opts[] = {
@@ -200,25 +200,12 @@ int main(int argc, char *argv[])
        f |= f_foreground;
        break;
 
-      case 'b': {
-       struct hostent *h = gethostbyname(optarg);
-       if (!h)
-         die(EXIT_FAILURE, "unknown host name `%s'", optarg);
-       memcpy(&baddr, h->h_addr, sizeof(struct in_addr));
-      } break;
-      case 'p': {
-       char *p;
-       unsigned long i = strtoul(optarg, &p, 0);
-       if (*p) {
-         struct servent *s = getservbyname(optarg, "udp");
-         if (!s)
-           die(EXIT_FAILURE, "unknown service name `%s'", optarg);
-         i = ntohs(s->s_port);
-       }
-       if (i >= 65536)
-         die(EXIT_FAILURE, "bad port number %lu", i);
-       port = i;
-      } break;
+      case 'b':
+       bindhost = optarg;
+       break;
+      case 'p':
+       bindsvc = optarg;
+       break;
       case 'n': {
        int i;
        for (i = 0;; i++) {
@@ -274,6 +261,17 @@ int main(int argc, char *argv[])
   if (!(~f & (f_daemon | f_foreground)))
     die(EXIT_FAILURE, "foreground operation for a daemon is silly");
 
+  aihint.ai_protocol = IPPROTO_UDP;
+  aihint.ai_socktype = SOCK_DGRAM;
+  aihint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+  if ((err = getaddrinfo(bindhost, bindsvc, &aihint, &ailist)) != 0) {
+    die(EXIT_FAILURE, "couldn't resolve hostname %c%s%c, port `%s': %s",
+       bindhost ? '`' : '<',
+       bindhost ? bindhost : "nil",
+       bindhost ? '\'' : '>',
+       bindsvc, gai_strerror(err));
+  }
+
   if (chdir(dir)) {
     die(EXIT_FAILURE, "can't set current directory to `%s': %s",
        dir, strerror(errno));
@@ -286,7 +284,7 @@ int main(int argc, char *argv[])
   signal(SIGPIPE, SIG_IGN);
   for (i = 0; tunnels[i]; i++)
     tunnels[i]->init();
-  p_init(baddr, port);
+  p_init(ailist); freeaddrinfo(ailist);
   if (!(f & f_daemon)) {
     af = AF_WARN;
 #ifndef NTRACE