int eSocket::connectToHost(eString hostname, int port) { sockaddr_in serv_addr; struct hostent *server; int res; if (mystate == Invalid) { /* the socket has been closed, create a new socket descriptor */ int s=socket(AF_INET, SOCK_STREAM, 0); mystate=Idle; setSocket(s, 1, mainloop); } if(socketdesc < 0){ error_(errno); return(-1); } server=gethostbyname(hostname.c_str()); if(server==NULL) { eDebug("can't resolve %s", hostname.c_str()); error_(errno); return(-2); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family=AF_INET; memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); serv_addr.sin_port=htons(port); res=::connect(socketdesc, (const sockaddr*)&serv_addr, sizeof(serv_addr)); if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR)) { eDebug("can't connect to host: %s", hostname.c_str()); close(); error_(errno); return(-3); } if (res < 0) // EINPROGRESS or EINTR { rsn->setRequested(rsn->getRequested()|eSocketNotifier::Write); mystate=Connecting; } else { mystate=Connection; connected_(); } return(0); }
int eUnixDomainSocket::connectToPath(eString path) { sockaddr_un serv_addr_un; int res; if (mystate == Invalid) { /* the socket has been closed, create a new socket descriptor */ int s=socket(AF_LOCAL, SOCK_STREAM, 0); mystate=Idle; setSocket(s, 1, mainloop); } if(socketdesc < 0){ error_(errno); return(-1); } memset(&serv_addr_un, 0, sizeof(serv_addr_un)); serv_addr_un.sun_family = AF_LOCAL; strcpy(serv_addr_un.sun_path, path.c_str()); res=::connect(socketdesc, (const sockaddr*)&serv_addr_un, sizeof(serv_addr_un)); if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR)) { close(); error_(errno); return(-3); } if (res < 0) // EINPROGRESS or EINTR { rsn->setRequested(rsn->getRequested()|eSocketNotifier::Write); mystate=Connecting; } else { mystate=Connection; connected_(); } return(0); }
int eSocket::connect(struct addrinfo *addr) { int res; struct addrinfo *ptr = addr; close(); for (ptr = addr; ptr != NULL; ptr = ptr->ai_next) { if (setSocket(socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol), 1) < 0) { /* No need to close, setSocket only fails when socket() already failed */ continue; } mystate = Idle; res = ::connect(socketdesc, ptr->ai_addr, ptr->ai_addrlen); if ((res < 0) && (errno != EINPROGRESS) && (errno != EINTR)) { error_(errno); close(); /* Release and disconnect the notifier */ continue; } if (res < 0) // EINPROGRESS or EINTR { rsn->setRequested(rsn->getRequested() | eSocketNotifier::Write); mystate = Connecting; return 0; } else { mystate = Connection; connected_(); return 1; } } return -1; }
void eSocket::notifier(int what) { if ((what & eSocketNotifier::Read) && (mystate == Connection)) { int bytesavail=256; if (issocket) if (ioctl(getDescriptor(), FIONREAD, &bytesavail)<0) eDebug("FIONREAD failed.\n"); { if (issocket) { if (!bytesavail) // does the REMOTE END has closed the connection? (no Hungup here!) { writebuffer.clear(); close(); return; } } else // when operating on terminals, check for break { serial_icounter_struct icount; memset(&icount, 0, sizeof(icount)); if (!ioctl(getDescriptor(), TIOCGICOUNT, &icount)) { if (last_break == -1) last_break = icount.brk; else if (last_break != icount.brk) { last_break = icount.brk; readbuffer.fromfile(getDescriptor(), bytesavail); readbuffer.clear(); writebuffer.clear(); rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); write(getDescriptor(), "BREAK!", 6); hangup(); return; } } else eDebug("TIOCGICOUNT failed(%m)"); } int r; if ((r=readbuffer.fromfile(getDescriptor(), bytesavail)) != bytesavail) if (issocket) eDebug("fromfile failed!"); readyRead_(); } } else if (what & eSocketNotifier::Write) { if ((mystate == Connection) || (mystate == Closing)) { if (!writebuffer.empty()) { bytesWritten_(writebuffer.tofile(getDescriptor(), 65536)); if (writebuffer.empty()) { rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); if (mystate == Closing) { close(); // warning, we might get destroyed after close. return; } } } else eDebug("got ready to write, but nothin in buffer. strange."); if (mystate == Closing) close(); } else if (mystate == Connecting) { mystate=Connection; rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); int res; socklen_t size=sizeof(res); ::getsockopt(getDescriptor(), SOL_SOCKET, SO_ERROR, &res, &size); if (!res) connected_(); else { close(); error_(res); } } } else if (what & eSocketNotifier::Hungup) { if (mystate == Connection || (mystate == Closing && issocket) ) { writebuffer.clear(); close(); } else if (mystate == Connecting) { int res; socklen_t size=sizeof(res); ::getsockopt(getDescriptor(), SOL_SOCKET, SO_ERROR, &res, &size); close(); error_(res); } } }
/* ls_startserver() */ int ls_startserver (char *host, char **server, int options) { int retsock; char official[MAXHOSTNAMELEN]; struct timeval timeout; struct sockaddr_in sin; int s; int descriptor[2]; struct resCmdBill cmdmsg; int resTimeout; socklen_t len; if (genParams_[LSF_RES_TIMEOUT].paramValue) resTimeout = atoi (genParams_[LSF_RES_TIMEOUT].paramValue); else resTimeout = RES_TIMEOUT; if (_isconnected_ (host, descriptor)) s = descriptor[0]; else if ((s = ls_connect (host)) < 0) return (-1); if (!FD_ISSET (s, &connection_ok_)) { FD_SET (s, &connection_ok_); if (ackReturnCode_ (s) < 0) { closesocket (s); _lostconnection_ (host); return (-1); } } if (!isatty (0) && !isatty (1)) options &= ~REXF_USEPTY; else if (options & REXF_USEPTY) { if (rstty_ (host) < 0) { _lostconnection_ (host); return (-1); } } if (mygetwd_ (cmdmsg.cwd) == 0) { closesocket (s); _lostconnection_ (host); lserrno = LSE_WDIR; return (-1); } if ((retsock = TcpCreate_ (TRUE, 0)) < 0) { closesocket (s); _lostconnection_ (host); return (-1); } len = sizeof (sin); if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0) { closesocket (retsock); closesocket (s); _lostconnection_ (host); lserrno = LSE_SOCK_SYS; return (-1); } cmdmsg.retport = sin.sin_port; cmdmsg.options = options & ~REXF_TASKPORT; cmdmsg.rpid = 0; cmdmsg.argv = server; timeout.tv_usec = 0; timeout.tv_sec = resTimeout; if (sendCmdBill_ (s, (resCmd) RES_SERVER, &cmdmsg, &retsock, &timeout) == -1) { closesocket (retsock); closesocket (s); _lostconnection_ (host); return (-1); } if (ackReturnCode_ (s) < 0) { closesocket (retsock); closesocket (s); _lostconnection_ (host); return (-1); } if (retsock <= 2 && (retsock = get_nonstd_desc_ (retsock)) < 0) { closesocket (s); _lostconnection_ (host); lserrno = LSE_SOCK_SYS; return (-1); } gethostbysock_ (s, official); (void) connected_ (official, -1, retsock, currentSN); return (retsock); } /* ls_startserver() */
int ls_connect(char *host) { struct hostent *hp; int s, descriptor[2], size; char official[MAXHOSTNAMELEN]; struct resConnect connReq; char *reqBuf; struct lsfAuth auth; int resTimeout; if (genParams_[LSF_RES_TIMEOUT].paramValue) resTimeout = atoi(genParams_[LSF_RES_TIMEOUT].paramValue); else resTimeout = RES_TIMEOUT; if (_isconnected_(host, descriptor)) return(descriptor[0]); if ((hp = Gethostbyname_(host)) == NULL) { lserrno = LSE_BAD_HOST; return -1; } strcpy(official, hp->h_name); memcpy((char *)&res_addr_.sin_addr,(char *)hp->h_addr,(int)hp->h_length); if ((rootuid_) && (genParams_[LSF_AUTH].paramValue == NULL)) { if (currentsocket_ > (FIRST_RES_SOCK + totsockets_ - 1)) { lserrno = LSE_NOMORE_SOCK; return -1; } s = currentsocket_; currentsocket_++; } else { if ((s = CreateSockEauth_(SOCK_STREAM)) < 0) return -1; } putEauthClientEnvVar("user"); putEauthServerEnvVar("res"); #ifdef INTER_DAEMON_AUTH putEnv("LSF_EAUTH_AUX_PASS", "yes"); #endif if (getAuth_(&auth, official) == -1) { closesocket(s); return -1; } runEsub_(&connReq.eexec, NULL); size = sizeof(struct LSFHeader) + sizeof(connReq) + sizeof(struct lsfAuth) + ALIGNWORD_(connReq.eexec.len) + sizeof(int) * 5 ; if ((reqBuf = malloc(size)) == NULL) { lserrno = LSE_MALLOC; goto Fail; } if (b_connect_(s, (struct sockaddr *)&res_addr_, sizeof(res_addr_), resTimeout) < 0) { lserrno = LSE_CONN_SYS; goto Fail; } if (callRes_(s, RES_CONNECT, (char *) &connReq, reqBuf, size, xdr_resConnect, 0, 0, &auth) == -1) { goto Fail; } if (connReq.eexec.len > 0) free(connReq.eexec.data); free(reqBuf); (void)connected_(official, s, -1, currentSN); return(s); Fail: CLOSESOCKET(s); if (connReq.eexec.len > 0) free(connReq.eexec.data); free(reqBuf); return -1; }