=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/plugin/mytcpio.c,v retrieving revision 1.3 retrieving revision 1.4.2.2 diff -u -p -r1.3 -r1.4.2.2 --- OpenXM/src/kan96xx/plugin/mytcpio.c 2000/03/20 01:53:47 1.3 +++ OpenXM/src/kan96xx/plugin/mytcpio.c 2000/11/11 04:44:30 1.4.2.2 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM/src/kan96xx/plugin/mytcpio.c,v 1.2 1999/10/30 02:22:16 takayama Exp $ */ +/* $OpenXM: OpenXM/src/kan96xx/plugin/mytcpio.c,v 1.4.2.1 2000/11/10 20:12:08 maekawa Exp $ */ #include #include #include @@ -29,53 +29,103 @@ int OpenedSocket = 0; extern int Quiet; socketOpen(char *serverName,int portNumber) { - static struct hostent *myhost; - static struct sockaddr_in me; - static int s_waiting; - static int on; - extern int errno; - int tt; + struct addrinfo hints, *res, *ai; + struct sockaddr_storage ss; + socklen_t len; + char pstr[BUFSIZ], *errstr; + int s, p, opt, error; - SET_TCPIOERROR; - fprintf(TcpioError,"Hello from open. serverName is %s and portnumber is %d\n", - serverName,portNumber); - if ((myhost = gethostbyname(serverName)) == NULL) { - errorMsg1s("Bad server name."); - return(-1); - } - bzero((char *)&me,sizeof(me)); - me.sin_family = AF_INET; - me.sin_port = htons(portNumber); - bcopy(myhost->h_addr, - &me.sin_addr,myhost->h_length); + SET_TCPIOERROR; + fprintf(TcpioError, "Hello from open. serverName is %s and " + "portnumber is %d\n", serverName, portNumber); - if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) { - errorMsg1s("Socket allocation is failed."); - return(-1); - } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - on=1; setsockopt(s_waiting,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); - /* important */ - if ((tt = bind(s_waiting,(struct sockaddr *) &me,sizeof(me))) == -1) { - fprintf(TcpioError,"Bind error. Error no is %d. See /usr/include/sys/errno.h. (asm/errno.h)\n",errno); - errorMsg1s("cannot bind"); - return(-1); - } - /* printf("bind returns %d\n",tt); */ - tt = sizeof(me); - if (getsockname(s_waiting,(struct sockaddr *)&me,&tt) < 0) { - fprintf(TcpioError,"getsockname error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); - errorMsg1s("cannot getsockname"); - return(-1); - } + memset(pstr, 0, sizeof(pstr)); + snprintf(pstr, sizeof(pstr), "%u", portNumber); - if (listen(s_waiting,1) < 0) { - errorMsg1s("Listen failed"); - return(-1); - } - fprintf(TcpioError,"Done the initialization. port =%d\n",ntohs(me.sin_port)); - OpenedSocket = ntohs(me.sin_port); - return(s_waiting); + error = getaddrinfo(serverName, pstr, &hints, &res); + if (error) { + errorMsg1s("Bad server name."); + return (-1); + } + + s = -1; + p = -1; + errstr = NULL; + + for (ai = res ; ai != NULL ; ai = ai->ai_next) { + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s < 0) { + errstr = "socket"; + continue; + } + + opt = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) { + errstr = "bind"; + close(s); + s = -1; + continue; + } + + len = sizeof(ss); + if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) { + errstr = "getsockname"; + close(s); + s = -1; + continue; + } + + switch (ss.ss_family) { + case AF_INET: + { + struct sockaddr_in *sin; + sin = (struct sockaddr_in *)&ss; + p = ntohs(sin->sin_port); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)&ss; + p = ntohs(sin6->sin6_port); + break; + } + default: + p = -1; + } + if (p < 0) { + errstr = "AF"; + close(s); + s = -1; + continue; + } + + if (listen(s, 1) < 0) { + errstr = "listen"; + close(s); + s = -1; + continue; + } + + break; + } + + freeaddrinfo(res); + + if (s < 0) { + fprintf(TcpioError, "Error: %s", errstr); + errorMsg1s(errstr); + } else { + OpenedSocket = p; + } + + return (s); } @@ -97,44 +147,77 @@ socketAccept(int snum) { return(news); } -socketAcceptLocal(int snum) { - int s, news; - struct sockaddr peer; - int len; - int i; +socketAcceptLocal(int s) { + struct sockaddr_storage ss; + socklen_t len; + int ps, accepted, error; - SET_TCPIOERROR; - s = snum; - fprintf(TcpioError,"Trying to accept from localhost... "); fflush(TcpioError); - len = sizeof(struct sockaddr); - if ((news = accept(s,&peer,&len)) < 0) { - errorMsg1s("Error in accept."); - return(-1); - } + SET_TCPIOERROR; - len = sizeof(struct sockaddr); - getpeername(news,&peer,&len); - printf("len= %d\n",len); - for (i=0; isin_addr.s_addr == INADDR_LOOPBACK) + accepted = 1; + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)&ss; + if (IN6_IS_ADDR_LOOPBACK(sin6->sin6_addr)) + accepted = 1; + break; + } + default: + accepted = 0; + } + + if (accepted) { + fprintf(stderr, "Authentication: " + "localhost is allowed to be accepted.\n"); + } else { + errorMsg1s("Authentication: " + "The connection is not from the localhost."); + close(s); + close(ps); + fprintf(stderr, "The connection is refused."); + return (-1); + } + + fprintf(TcpioError, "Accepted.\n"); + fflush(TcpioError); + if (close(s) < 0) { + errorMsg1s("Error in closing the old socket."); + close(ps); + return(-1); + } + + return(ps); } int oxSocketSelect0(int fd,int t) {