From owner-IPv6-jp@jp.freebsd.org  Sat Oct 20 07:22:45 2001
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id HAA12285;
	Sat, 20 Oct 2001 07:22:45 +0900 (JST)
	(envelope-from owner-IPv6-jp@jp.FreeBSD.org)
Received: from sahiro.homeip.net (p82-dna05sawada.niigata.ocn.ne.jp [211.122.195.210])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id HAA12280
	for <IPv6-jp@jp.freebsd.org>; Sat, 20 Oct 2001 07:22:41 +0900 (JST)
	(envelope-from sahiro@crest.ocn.ne.jp)
Date: Sat, 20 Oct 2001 07:23:00 +0900
From: SASAKI Katuhiro <sahiro@crest.ocn.ne.jp>
To: IPv6-jp@jp.freebsd.org
Message-ID: <3bd0a7c4.6451%sahiro@crest.ocn.ne.jp>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP
Reply-To: IPv6-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+010328
X-Sequence: IPv6-jp 1005
Subject: [IPv6-jp 1005] IPv6 =?ISO-2022-JP?B?GyRCJVElQyVBGyhC?= for
 clockspeed-0.62
Errors-To: owner-IPv6-jp@jp.freebsd.org
Sender: owner-IPv6-jp@jp.freebsd.org
X-Originator: sahiro@crest.ocn.ne.jp

$B!!$5$5$-$G$9!#(B
$B!!:G6a(BIPv6$B%M%C%H%o!<%/$r;n$7$?$/$J$C$F!"K?;o$NG_K\$5$s$NO":\$d@h(B
$BF|9XF~$7$?=q@R$r;29M$K$7$F$]$D$]$D$H:n6H$r$7$F$$$^$9!#(B
# $B$C$F$b!":o$C$F$$$?%+!<%M%k%*%W%7%g%s$rF~$lD>$7$F%+!<%M%k$N:F9=(B
# $BC[$r$7$F!V$*$)!"(Bv6$B$J%"%I%l%9$D$$$H$k!*!W$H$+8@$C$F$$$kCJ3,$G$9(B
# $B$,!#(B

$B!!$=$l$O$5$F$*$-!#$=$s$J$U$&$K$7$FM7$s$G$$$?$H$3$m!"F|:"MxMQ$7$F(B
$B$$$k%=%U%H%&%'%"$N0l$D$G$"$k(Bclockspeed-0.62
(http://cr.yp.to/clockspeed.html)$B$,(BIPv6$B$rC}$C$F$/$l$J$$$h$&$J$N(B
$B$G!"K?;o$N?@L@$5$s$N5-;v$r;29M$K$7$F4JC1$J%Q%C%A$r:n$C$F$_$^$7(B
$B$?!#(B
$B!!$3$s$J$b$N$r%]%9%H$7$F$b4n$V?M$,$$$k$N$+$I$&$+$H$$$&$N$O!"$O$J(B
$B$O$@5?Ld$G$O$"$k$N$G$9$,!D!D!#(B

$B!!$J$*!"%Q%C%A$K$*$+$7$J2U=j!&2~NI$9$Y$-E@!JB??tB8:_$9$k$H;W$$(B
$B$^$9!#!K$J$I$"$j$^$7$?$i!"%3%a%s%H$J$I$7$F$$$?$@$1$k$H%P%+$,4n$S(B
$B$^$9$N$G!"$h$m$7$/$*4j$$$$$?$7$^$9!#(B
$B!!$=$l$G$O!#(B


Index: sntpclock.c
===================================================================
RCS file: /var/cvs/devel/clockspeed/sntpclock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -r1.1.1.1 -r1.5
--- sntpclock.c	2001/10/13 08:25:16	1.1.1.1
+++ sntpclock.c	2001/10/15 07:04:27	1.5
@@ -3,6 +3,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include "strerr.h"
 #include "ip.h"
 #include "str.h"
@@ -84,14 +85,14 @@
 #define FATAL "sntpclock: fatal: "
 #define WARNING "sntpclock: warning: "
 
+#define NTPPORT "123"
+
 void die_usage()
 {
-  strerr_die1x(100,"sntpclock: usage: sntpclock ip.ad.dr.ess");
+  strerr_die1x(100,"sntpclock: usage: sntpclock ip.ad.dr.ess or host.name");
 }
 
 char *host;
-struct ip_address ipremote;
-struct sockaddr_in sa;
 int s;
 
 unsigned char query[48];
@@ -121,14 +122,19 @@
 int argc;
 char **argv;
 {
+  struct addrinfo *info;
+  struct addrinfo *ai;
+  struct addrinfo hints;
   struct timeval tvselect;
   fd_set rfds;
-  char *x;
   unsigned long u;
   int r;
   int loop;
   struct timeval tvcookie;
   int flagleap;
+  int smax;
+  int send_ok;
+  int recv_ok;
 
   taia_unpack(initdeltamin,&deltamin);
   taia_unpack(initdeltamax,&deltamax);
@@ -142,85 +148,118 @@
   host = argv[1];
   if (!host) die_usage();
   if (!str_diff(host,"0")) host = "127.0.0.1";
-  if (host[ip_scan(host,&ipremote)]) die_usage();
-
-  s = socket(AF_INET,SOCK_DGRAM,0);
-  if (s == -1)
-    strerr_die2sys(111,FATAL,"unable to create socket: ");
-
-  byte_zero(&sa,sizeof(sa));
-  byte_copy(&sa.sin_addr,4,&ipremote);
-  x = (char *) &sa.sin_port;
-  x[0] = 0;
-  x[1] = 123; /* NTP */
-  sa.sin_family = AF_INET;
-
-  for (loop = 0;loop < 10;++loop) {
-    byte_zero(query,sizeof query);
-    query[0] = 27; /* client, NTP version 3 */
-    query[2] = 8;
-  
-    gettimeofday(&tvcookie,(struct timezone *) 0);
-    u = tvcookie.tv_sec + NTP_OFFSET;
-    query[43] = u; u >>= 8;
-    query[42] = u; u >>= 8;
-    query[41] = u; u >>= 8;
-    query[40] = u;
-    u = tvcookie.tv_usec;
-    query[45] = u; u >>= 8; /* deliberately inaccurate; this is a cookie */
-    query[44] = u;
-    u = getpid();
-    query[47] = u; u >>= 8;
-    query[46] = u;
+  byte_zero(&hints, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_protocol = IPPROTO_UDP;
+  if (getaddrinfo(host, NTPPORT, &hints, &info) != 0) {
+	  die_usage();
+  }
+
+  smax = -1;
+  send_ok = 0;
+  recv_ok = 0;
+  for (ai = info; ai != NULL; ai = ai->ai_next) {
+	  s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+	  if (s < 0) {
+		  continue;
+	  }
+	  if (s >= FD_SETSIZE) {
+		  close(s);
+		  continue;
+	  }
+	  if (s > smax) {
+		  smax = s;
+	  }
+
+	  for (loop = 0;loop < 10;++loop) {
+		  byte_zero(query,sizeof query);
+		  query[0] = 27; /* client, NTP version 3 */
+		  query[2] = 8;
+
+		  gettimeofday(&tvcookie,(struct timezone *) 0);
+		  u = tvcookie.tv_sec + NTP_OFFSET;
+		  query[43] = u; u >>= 8;
+		  query[42] = u; u >>= 8;
+		  query[41] = u; u >>= 8;
+		  query[40] = u;
+		  u = tvcookie.tv_usec;
+		  /* deliberately inaccurate; this is a cookie */
+		  query[45] = u; u >>= 8;
+		  query[44] = u;
+		  u = getpid();
+		  query[47] = u; u >>= 8;
+		  query[46] = u;
   
-    taia_now(&ta0);
-    if (sendto(s,query,sizeof query,0,(struct sockaddr *) &sa,sizeof sa) == -1)
-      strerr_die2sys(111,FATAL,"unable to send request: ");
-    FD_ZERO(&rfds);
-    FD_SET(s,&rfds);
-    tvselect.tv_sec = 1;
-    tvselect.tv_usec = 0;
-    if (select(s + 1,&rfds,(fd_set *) 0,(fd_set *) 0,&tvselect) != 1) {
-      strerr_warn2(WARNING,"unable to read clock: timed out",0);
-      continue;
-    }
-    r = recv(s,response,sizeof response,0);
-    if (r == -1) {
-      strerr_warn2(WARNING,"unable to read clock: ",&strerr_sys);
-      continue;
-    }
-    taia_now(&ta1);
-    if (   (r < 48)
-	|| (r >= sizeof response)
-	|| (((response[0] & 7) != 2) && ((response[0] & 7) != 4))
-	|| !(response[0] & 56)
-	|| byte_diff(query + 40,8,response + 24)
-       ) {
-      strerr_warn2(WARNING,"unable to read clock: bad response format",0);
-      continue;
-    }
-
-    flagleap = ((response[0] & 192) == 64);
-
-    ntp_taia(response + 32,&taremote,flagleap);
-    taia_add(&taremote,&taremote,&deltaoffset);
-
-    taia_add(&temp1,&deltamax,&ta0);
-    taia_add(&temp2,&deltamin,&ta0);
-    if (taia_less(&taremote,&temp1) && !taia_less(&taremote,&temp2)) {
-      taia_sub(&temp1,&taremote,&ta0);
-      deltamax = temp1;
-    }
+		  taia_now(&ta0);
+		  if (sendto(s,query,sizeof query,0,
+			     ai->ai_addr,ai->ai_addrlen) < 0) {
+			  continue;
+		  }
+		  send_ok = 1;
+		  FD_ZERO(&rfds);
+		  FD_SET(s,&rfds);
+		  tvselect.tv_sec = 1;
+		  tvselect.tv_usec = 0;
+		  if (select(s + 1,&rfds,
+			     (fd_set *) 0,(fd_set *) 0,&tvselect) != 1) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: timed out",0);
+			  continue;
+		  }
+		  r = recv(s,response,sizeof response,0);
+		  if (r == -1) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: ",&strerr_sys);
+			  continue;
+		  }
+		  taia_now(&ta1);
+		  if (   (r < 48)
+			 || (r >= sizeof response)
+			 || (((response[0] & 7) != 2) &&
+			     ((response[0] & 7) != 4))
+			 || !(response[0] & 56)
+			 || byte_diff(query + 40,8,response + 24)
+			  ) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: bad response format",0);
+			  continue;
+		  }
+		  recv_ok = 1;
+
+		  flagleap = ((response[0] & 192) == 64);
+
+		  ntp_taia(response + 32,&taremote,flagleap);
+		  taia_add(&taremote,&taremote,&deltaoffset);
+
+		  taia_add(&temp1,&deltamax,&ta0);
+		  taia_add(&temp2,&deltamin,&ta0);
+		  if (taia_less(&taremote,&temp1) &&
+		      !taia_less(&taremote,&temp2)) {
+			  taia_sub(&temp1,&taremote,&ta0);
+			  deltamax = temp1;
+		  }
 
-    ntp_taia(response + 40,&taremote,flagleap);
-    taia_add(&taremote,&taremote,&deltaoffset);
+		  ntp_taia(response + 40,&taremote,flagleap);
+		  taia_add(&taremote,&taremote,&deltaoffset);
   
-    taia_add(&temp1,&deltamax,&ta1);
-    taia_add(&temp2,&deltamin,&ta1);
-    if (taia_less(&temp2,&taremote) && !taia_less(&temp1,&taremote)) {
-      taia_sub(&temp2,&taremote,&ta1);
-      deltamin = temp2;
-    }
+		  taia_add(&temp1,&deltamax,&ta1);
+		  taia_add(&temp2,&deltamin,&ta1);
+		  if (taia_less(&temp2,&taremote) &&
+		      !taia_less(&temp1,&taremote)) {
+			  taia_sub(&temp2,&taremote,&ta1);
+			  deltamin = temp2;
+		  }
+	  }
+	  if (recv_ok) {
+		  break;
+	  }
+  }
+  if (smax < 0) {
+	  strerr_die2sys(111,FATAL,"unable to create socket: ");
+  }
+  if (!send_ok) {
+	  strerr_die2sys(111,FATAL,"unable to send request: ");
   }
 
   taia_sub(&temp1,&deltamax,&deltamin);
Index: taiclock.c
===================================================================
RCS file: /var/cvs/devel/clockspeed/taiclock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -r1.1.1.1 -r1.6
--- taiclock.c	2001/10/13 08:25:16	1.1.1.1
+++ taiclock.c	2001/10/15 07:12:20	1.6
@@ -3,6 +3,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include "strerr.h"
 #include "ip.h"
 #include "str.h"
@@ -18,14 +19,14 @@
 #define FATAL "taiclock: fatal: "
 #define WARNING "taiclock: warning: "
 
+#define PORT "4014"
+
 void die_usage()
 {
   strerr_die1x(100,"taiclock: usage: taiclock ip.ad.dr.ess");
 }
 
 char *host;
-struct ip_address ipremote;
-struct sockaddr_in sa;
 int s;
 
 char initdeltaoffset[] = {0,0,0,0,0,2,163,0,0,0,0,0,0,0,0,0};
@@ -55,12 +56,17 @@
 int argc;
 char **argv;
 {
+  struct addrinfo *info;
+  struct addrinfo *ai;
+  struct addrinfo hints;
   struct timeval tvselect;
   fd_set rfds;
-  char *x;
   unsigned long u;
   int r;
   int loop;
+  int smax;
+  int send_ok;
+  int recv_ok;
 
   taia_unpack(initdeltamin,&deltamin);
   taia_unpack(initdeltamax,&deltamax);
@@ -71,74 +77,105 @@
   host = argv[1];
   if (!host) die_usage();
   if (!str_diff(host,"0")) host = "127.0.0.1";
-  if (host[ip_scan(host,&ipremote)]) die_usage();
-
-  s = socket(AF_INET,SOCK_DGRAM,0);
-  if (s == -1)
-    strerr_die2sys(111,FATAL,"unable to create socket: ");
-
-  byte_zero(&sa,sizeof(sa));
-  byte_copy(&sa.sin_addr,4,&ipremote);
-  x = (char *) &sa.sin_port;
-  x[0] = 15;
-  x[1] = 174;
-  sa.sin_family = AF_INET;
-
-  for (loop = 0;loop < 10;++loop) {
-    byte_zero(query,sizeof query);
-    query[0] = 'c';
-    query[1] = 't';
-    query[2] = 'a';
-    query[3] = 'i';
-
-    /* XXX: cookie-building time */
-    taia_now(&ta0);
-    taia_pack(query + 16,&ta0);
-    u = getpid();
-    query[30] = u; u >>= 8;
-    query[31] = u;
-
-    taia_now(&ta0);
-    if (sendto(s,query,sizeof query,0,(struct sockaddr *) &sa,sizeof sa) == -1)
-      strerr_die2sys(111,FATAL,"unable to send request: ");
-    FD_ZERO(&rfds);
-    FD_SET(s,&rfds);
-    tvselect.tv_sec = 1;
-    tvselect.tv_usec = 0;
-    if (select(s + 1,&rfds,(fd_set *) 0,(fd_set *) 0,&tvselect) != 1) {
-      strerr_warn2(WARNING,"unable to read clock: timed out",0);
-      continue;
-    }
-    r = recv(s,response,sizeof response,0);
-    if (r == -1) {
-      strerr_warn2(WARNING,"unable to read clock: ",&strerr_sys);
-      continue;
-    }
-    taia_now(&ta1);
-    if (   (r != sizeof response)
-	|| (response[0] != 's')
-	|| byte_diff(query + 1,3,response + 1)
-	|| byte_diff(query + 20,12,response + 20)
-       ) {
-      strerr_warn2(WARNING,"unable to read clock: bad response format",0);
-      continue;
-    }
-
-    taia_unpack(response + 4,&taremote);
-    taia_add(&taremote,&taremote,&deltaoffset);
-
-    taia_add(&temp1,&deltamax,&ta0);
-    taia_add(&temp2,&deltamin,&ta0);
-    if (taia_less(&taremote,&temp1) && !taia_less(&taremote,&temp2)) {
-      taia_sub(&temp1,&taremote,&ta0);
-      deltamax = temp1;
-    }
-    taia_add(&temp1,&deltamax,&ta1);
-    taia_add(&temp2,&deltamin,&ta1);
-    if (taia_less(&temp2,&taremote) && !taia_less(&temp1,&taremote)) {
-      taia_sub(&temp2,&taremote,&ta1);
-      deltamin = temp2;
-    }
+  byte_zero(&hints, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_protocol = IPPROTO_UDP;
+  if (getaddrinfo(host, PORT, &hints, &info) != 0) {
+	  die_usage();
+  }
+
+  smax = -1;
+  send_ok = 0;
+  recv_ok = 0;
+  for (ai = info; ai != NULL; ai = ai->ai_next) {
+	  s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+	  if (s < 0) {
+		  continue;
+	  }
+	  if (s >= FD_SETSIZE) {
+		  close(s);
+		  continue;
+	  }
+	  if (s > smax) {
+		  smax = s;
+	  }
+
+	  for (loop = 0;loop < 10;++loop) {
+		  byte_zero(query,sizeof query);
+		  query[0] = 'c';
+		  query[1] = 't';
+		  query[2] = 'a';
+		  query[3] = 'i';
+
+		  /* XXX: cookie-building time */
+		  taia_now(&ta0);
+		  taia_pack(query + 16,&ta0);
+		  u = getpid();
+		  query[30] = u; u >>= 8;
+		  query[31] = u;
+
+		  taia_now(&ta0);
+		  if (sendto(s,query,sizeof query,0,
+			     ai->ai_addr,ai->ai_addrlen) < 0) {
+			  continue;
+		  }
+		  send_ok = 1;
+		  FD_ZERO(&rfds);
+		  FD_SET(s,&rfds);
+		  tvselect.tv_sec = 1;
+		  tvselect.tv_usec = 0;
+		  if (select(s + 1,&rfds,
+			     (fd_set *) 0,(fd_set *) 0,&tvselect) != 1) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: timed out",0);
+			  continue;
+		  }
+		  r = recv(s,response,sizeof response,0);
+		  if (r == -1) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: ",&strerr_sys);
+			  continue;
+		  }
+		  taia_now(&ta1);
+		  if (   (r != sizeof response)
+			 || (response[0] != 's')
+			 || byte_diff(query + 1,3,response + 1)
+			 || byte_diff(query + 20,12,response + 20)
+			  ) {
+			  strerr_warn2(WARNING,
+				       "unable to read clock: bad response format",0);
+			  continue;
+		  }
+		  recv_ok = 1;
+
+		  taia_unpack(response + 4,&taremote);
+		  taia_add(&taremote,&taremote,&deltaoffset);
+
+		  taia_add(&temp1,&deltamax,&ta0);
+		  taia_add(&temp2,&deltamin,&ta0);
+		  if (taia_less(&taremote,&temp1)
+		      && !taia_less(&taremote,&temp2)) {
+			  taia_sub(&temp1,&taremote,&ta0);
+			  deltamax = temp1;
+		  }
+		  taia_add(&temp1,&deltamax,&ta1);
+		  taia_add(&temp2,&deltamin,&ta1);
+		  if (taia_less(&temp2,&taremote) &&
+		      !taia_less(&temp1,&taremote)) {
+			  taia_sub(&temp2,&taremote,&ta1);
+			  deltamin = temp2;
+		  }
+	  }
+	  if (recv_ok) {
+		  break;
+	  }
+  }
+  if (smax < 0) {
+	  strerr_die2sys(111,FATAL,"unable to create socket: ");
+  }
+  if (!send_ok) {
+	  strerr_die2sys(111,FATAL,"unable to send request: ");
   }
 
   taia_sub(&temp1,&deltamax,&deltamin);
Index: taiclockd.c
===================================================================
RCS file: /var/cvs/devel/clockspeed/taiclockd.c,v
retrieving revision 1.1.1.1
retrieving revision 1.9
diff -u -r1.1.1.1 -r1.9
--- taiclockd.c	2001/10/13 08:25:16	1.1.1.1
+++ taiclockd.c	2001/10/15 07:47:53	1.9
@@ -3,49 +3,193 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <unistd.h>
 #include "taia.h"
 #include "byte.h"
 #include "strerr.h"
 
 #define FATAL "taiclockd: fatal: "
+#define WARNING "taiclockd: warning: "
 
-unsigned char packet[256];
-struct sockaddr_in sa;
-int s;
+#define PORT "4014"
 
+unsigned char packet[256];
 struct taia ta;
 
+struct node_sock_list {
+	int sock;
+	struct node_sock_list *next;
+};
+
+void bindall(const struct addrinfo *info, struct node_sock_list **sl,
+	     int *maxsock, int *bindcount);
+
+void cleanup(struct addrinfo *ai, fd_set *fdset, struct node_sock_list *top);
+
 void main(argc,argv)
 int argc;
 char **argv;
 {
-  char *x;
+  struct addrinfo *info;
+  struct addrinfo hints;
+  struct node_sock_list *sl_top;
+  struct node_sock_list *pos;
+  fd_set *readfds;
+  size_t szreadfds;
+  struct sockaddr_storage ss;
   int len;
+  int maxsock;
+  int bindcount;
   int r;
 
-  s = socket(AF_INET,SOCK_DGRAM,0);
-  if (s == -1)
-    strerr_die2sys(111,FATAL,"unable to create socket: ");
-
-  byte_zero(&sa,sizeof(sa));
-  x = (char *) &sa.sin_port;
-  x[0] = 15;
-  x[1] = 174;
-  sa.sin_family = AF_INET;
+  byte_zero(&hints, sizeof(hints));
+  hints.ai_flags = AI_PASSIVE;
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_DGRAM;
+  hints.ai_protocol = IPPROTO_UDP;
+  if (getaddrinfo(NULL, PORT, &hints, &info) != 0) {
+	  strerr_die2sys(111,FATAL,"unable to get address information: ");
+  }
 
-  if (bind(s,(struct sockaddr *) &sa,sizeof sa) == -1)
-    strerr_die2sys(111,FATAL,"unable to bind: ");
+  bindall(info, &sl_top, &maxsock, &bindcount);
+  if (maxsock < 0) {
+	  cleanup(info, readfds, sl_top);
+	  strerr_die2sys(111,FATAL,"unable to create socket: ");
+  }
+  if (bindcount == 0) {
+	  cleanup(info, readfds, sl_top);
+	  strerr_die2sys(111,FATAL,"unable to bind: ");
+  }
+  if (sl_top == NULL) {
+	  cleanup(info, readfds, sl_top);
+	  strerr_die2sys(111,FATAL,"unable to allocate memory: ");
+  }
 
+  szreadfds = howmany(maxsock + 1, NFDBITS) * sizeof(fd_mask);
+  readfds  = (fd_set *)malloc(szreadfds);
+  if (readfds == NULL) {
+	  cleanup(info, readfds, sl_top);
+	  strerr_die2sys(111,FATAL,"unable to allocate memory: ");
+  }
   for (;;) {
-    len = sizeof sa;
-    r = recvfrom(s,packet,sizeof packet,0,(struct sockaddr *) &sa,&len);
-    if (r >= 20)
-      if (!byte_diff(packet,4,"ctai")) {
-	packet[0] = 's';
-        taia_now(&ta);
-        taia_pack(packet + 4,&ta);
-        sendto(s,packet,r,0,(struct sockaddr *) &sa,len);
-	  /* if it fails, bummer */
-      }
+	  byte_zero(readfds, szreadfds);
+	  for (pos = sl_top; pos != NULL; pos = pos->next) {
+		  FD_SET(pos->sock, readfds);
+	  }
+	  for (;;) {
+		  if (select(maxsock + 1, readfds, NULL, NULL, NULL) > 0) {
+			  break;
+		  }
+		  strerr_warn2(WARNING, "retry select(): ",0);
+	  }
+	  for (pos = sl_top; pos != NULL; pos = pos->next) {
+		  if (FD_ISSET(pos->sock, readfds)) {
+			  len = sizeof(ss);
+			  r = recvfrom(pos->sock,packet,sizeof packet,
+				       0,(struct sockaddr *) &ss,&len);
+			  if (r >= 20) {
+				  if (!byte_diff(packet,4,"ctai")) {
+					  packet[0] = 's';
+					  taia_now(&ta);
+					  taia_pack(packet + 4,&ta);
+					  sendto(pos->sock,packet,r,0,
+						 (struct sockaddr *) &ss,len);
+					  /* if it fails, bummer */
+				  }
+			  }
+
+		  }
+	  }
   }
+}
+
+void bindall(const struct addrinfo *info, struct node_sock_list **sl,
+	    int *maxsock, int *bindcount)
+{
+	struct addrinfo *ai;
+	struct node_sock_list *top = NULL;
+	struct node_sock_list *nsl;
+	struct node_sock_list **pos = &top;
+	int max = -1;
+	int count = 0;
+	int sock;
+
+	for (ai = info; ai != NULL; ai = ai->ai_next) {
+		if (ai->ai_family == AF_INET6) {
+			sock = socket(ai->ai_family, ai->ai_socktype,
+				      ai->ai_protocol);
+			if (sock < 0) {
+				continue;
+			}
+			if (sock > max) {
+				max = sock;
+			}
+			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+				close(sock);
+				continue;
+			}
+			count++;
+			nsl = (struct node_sock_list *)
+				malloc(sizeof(struct node_sock_list));
+			if (nsl == NULL) {
+				close(sock);
+				continue;
+			}
+			nsl->sock = sock;
+			nsl->next = NULL;
+			*pos = nsl;
+			pos = &nsl->next;
+		}
+	}
+	for (ai = info; ai != NULL; ai = ai->ai_next) {
+		if (ai->ai_family == AF_INET) {
+			sock = socket(ai->ai_family, ai->ai_socktype,
+				      ai->ai_protocol);
+			if (sock < 0) {
+				continue;
+			}
+			if (sock > max) {
+				max = sock;
+			}
+			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+				close(sock);
+				continue;
+			}
+			count++;
+			nsl = (struct node_sock_list *)
+				malloc(sizeof(struct node_sock_list));
+			if (nsl == NULL) {
+				close(sock);
+				continue;
+			}
+			nsl->sock = sock;
+			nsl->next = NULL;
+			*pos = nsl;
+			pos = &nsl->next;
+		}
+	}
+
+	*sl = top;
+	*maxsock = max;
+	*bindcount = count;
+}
+
+void cleanup(struct addrinfo *ai, fd_set *fdset, struct node_sock_list *top)
+{
+	struct node_sock_list *cur;
+	struct node_sock_list *next;
+
+	if (ai != NULL) {
+		freeaddrinfo(ai);
+	}
+	if (fdset != NULL) {
+		free(fdset);
+	}
+	for (cur = top; cur != NULL; cur = next) {
+		next = cur->next;
+		close(cur->sock);
+		free(cur);
+	}
 }


================================================================
                       SASAKI Katuhiro

                mailto: sahiro@crest.ocn.ne.jp
================================================================
