=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/plugin/mytcpio.c,v retrieving revision 1.1 retrieving revision 1.4.2.2 diff -u -p -r1.1 -r1.4.2.2 --- OpenXM/src/kan96xx/plugin/mytcpio.c 1999/10/08 02:12:05 1.1 +++ OpenXM/src/kan96xx/plugin/mytcpio.c 2000/11/11 04:44:30 1.4.2.2 @@ -1,3 +1,4 @@ +/* $OpenXM: OpenXM/src/kan96xx/plugin/mytcpio.c,v 1.4.2.1 2000/11/10 20:12:08 maekawa Exp $ */ #include #include #include @@ -22,64 +23,116 @@ static void errorMsg1s(char *s) { fprintf(stderr,"%s\n",s); } -FILE *TcpioError = stdout; +#define SET_TCPIOERROR { if (TcpioError == NULL) TcpioError = stdout; } +FILE *TcpioError = NULL; 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); - 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); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) { - errorMsg1s("Socket allocation is failed."); - return(-1); - } + memset(pstr, 0, sizeof(pstr)); + snprintf(pstr, sizeof(pstr), "%u", portNumber); - 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); - } + error = getaddrinfo(serverName, pstr, &hints, &res); + if (error) { + errorMsg1s("Bad server name."); + return (-1); + } - 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); + 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); } socketAccept(int snum) { int s, news; + SET_TCPIOERROR; s = snum; fprintf(TcpioError,"Trying to accept... "); fflush(TcpioError); if ((news = accept(s,NULL,NULL)) < 0) { @@ -94,43 +147,77 @@ socketAccept(int snum) { return(news); } -socketAcceptLocal(int snum) { - int s, news; - struct sockaddr peer; - int len; - int i; - - 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); - } +socketAcceptLocal(int s) { + struct sockaddr_storage ss; + socklen_t len; + int ps, accepted, error; - 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) { @@ -138,6 +225,7 @@ int oxSocketSelect0(int fd,int t) { struct timeval timeout; int debug = 0; extern int errno; + SET_TCPIOERROR; FD_ZERO(&readfds); FD_SET(fd,&readfds); timeout.tv_sec = 0; @@ -170,6 +258,7 @@ oxSocketMultiSelect(int sid[],int size,int t,int resul int isdata = 0; extern errno; + SET_TCPIOERROR; FD_ZERO(&readfds); timeout.tv_sec = 0; timeout.tv_usec = (long)t; @@ -219,6 +308,7 @@ socketConnect(char *serverName,int portNumber) { int socketid; int on; + SET_TCPIOERROR; if ((servhost = gethostbyname(serverName)) == NULL) { errorMsg1s("bad server name.\n"); return(-1); @@ -249,10 +339,11 @@ socketConnectWithPass(char *servername,int port,char * { int fd; int m; + SET_TCPIOERROR; fd = socketConnect(servername,port); if (fd >= 0) { - m = write(fd,pass,strlen(pass)); - if (m != strlen(pass)) { + m = write(fd,pass,strlen(pass)+1); + if (m != strlen(pass)+1) { fprintf(TcpioError,"Fail to send password to fd=%d.\n",fd); return(-1); }