int tcpstrtoconnect(int sock,const char *hostname,const char *service,uint32_t msecto) { struct sockaddr_in sa; if (socknonblock(sock)<0) { return -1; } if (sockaddrfill(&sa,hostname,service,AF_INET,SOCK_STREAM,0)<0) { return -1; } if (connect(sock,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)) >= 0) { return 0; } if (errno == EINPROGRESS) { struct pollfd pfd; pfd.fd = sock; pfd.events = POLLOUT; pfd.revents = 0; if (poll(&pfd,1,msecto)<0) { return -1; } if (pfd.revents & POLLOUT) { return tcpgetstatus(sock); } errno=ETIMEDOUT; } return -1; }
static int rep_wait_for_connection(replication *r,uint32_t msecto) { uint8_t i,l; struct timeval tvb,tv; uint32_t msec; gettimeofday(&tvb,NULL); for (;;) { l=1; for (i=0 ; i<r->srccnt ; i++) { if (r->repsources[i].mode==CONNECTING) { r->fds[i].events = POLLOUT; l=0; } else { r->fds[i].events = 0; } } if (l) { // finished return 0; } gettimeofday(&tv,NULL); if (tv.tv_usec < tvb.tv_usec) { tv.tv_usec+=1000000; tv.tv_sec--; } tv.tv_sec-=tvb.tv_sec; tv.tv_usec-=tvb.tv_usec; msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; if (msec>=msecto) { syslog(LOG_NOTICE,"replicator: connect timed out"); return -1; // timed out } if (poll(r->fds,r->srccnt,msecto-msec)<0) { if (errno!=EINTR && errno!=EAGAIN) { mfs_errlog_silent(LOG_NOTICE,"replicator: poll error"); return -1; } continue; } for (i=0 ; i<r->srccnt ; i++) { if (r->fds[i].revents & POLLHUP) { syslog(LOG_NOTICE,"replicator: connection lost"); return -1; } if (r->fds[i].revents & POLLOUT) { if (tcpgetstatus(r->repsources[i].sock)<0) { mfs_errlog_silent(LOG_NOTICE,"replicator: connect error"); return -1; } r->repsources[i].mode=IDLE; } } } }
void masterconn_connecttest(serventry *eptr) { int status; status = tcpgetstatus(eptr->sock); if (status) { MFSLOG(LOG_WARNING,"connection failed, error: %m"); tcpclose(eptr->sock); eptr->sock=-1; eptr->mode=FREE; } else { MFSLOG(LOG_NOTICE,"connected to Master"); masterconn_connected(eptr); } }
void masterconn_connecttest(masterconn *eptr) { int status; status = tcpgetstatus(eptr->sock); if (status) { mfs_errlog_silent(LOG_WARNING,"connection failed, error"); tcpclose(eptr->sock); eptr->sock = -1; eptr->mode = FREE; eptr->masteraddrvalid = 0; } else { syslog(LOG_NOTICE,"connected to Master"); masterconn_connected(eptr); } }
static int rep_wait_for_connection(replication *r,uint32_t msecto) { uint8_t i,l; uint64_t st; uint32_t msec; st = monotonic_useconds(); for (;;) { l=1; for (i=0 ; i<r->srccnt ; i++) { if (r->repsources[i].mode==CONNECTING) { r->fds[i].events = POLLOUT; l=0; } else { r->fds[i].events = 0; } } if (l) { // finished return 0; } msec = (monotonic_useconds()-st)/1000; if (msec>=msecto) { syslog(LOG_NOTICE,"replicator: connect timed out"); return -1; // timed out } if (poll(r->fds,r->srccnt,msecto-msec)<0) { if (errno!=EINTR && ERRNO_ERROR) { mfs_errlog_silent(LOG_NOTICE,"replicator: poll error"); return -1; } continue; } for (i=0 ; i<r->srccnt ; i++) { if (r->fds[i].revents & POLLHUP) { syslog(LOG_NOTICE,"replicator: connection lost"); return -1; } if (r->fds[i].revents & POLLOUT) { if (tcpgetstatus(r->repsources[i].sock)<0) { mfs_errlog_silent(LOG_NOTICE,"replicator: connect error"); return -1; } r->repsources[i].mode=IDLE; } } } }
int tcpnumtoconnect(int sock,uint32_t ip,uint16_t port,uint32_t msecto) { struct sockaddr_in sa; if (socknonblock(sock)<0) { return -1; } sockaddrnumfill(&sa,ip,port); if (connect(sock,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)) >= 0) { return 0; } if (errno == EINPROGRESS) { struct pollfd pfd; pfd.fd = sock; pfd.events = POLLOUT; pfd.revents = 0; if (poll(&pfd,1,msecto)<0) { return -1; } if (pfd.revents & POLLOUT) { return tcpgetstatus(sock); } errno=ETIMEDOUT; } return -1; }