#include "tlog.h"
#include "tmalloc.h"
+static u_int32_t
+setlinger( TC_Connection *cs ) {
+ struct linger ling;
+ int val = 0;
+ socklen_t size = sizeof(val);
+
+ if (getsockopt(cs->fd, SOL_SOCKET,SO_ERROR,&val,&size) == -1) {
+ tlog(TL_ALARM,"getsockopt: %s:%d - %s(%d)",inet_ntoa(cs->serv_addr.sin_addr),
+ ntohs(cs->serv_addr.sin_port), strerror(errno), errno);
+ shutdown(cs->fd,SHUT_RDWR);
+ close(cs->fd);
+ cs->fd = 0;
+ cs->state = CS_ERROR;
+ return CS_ERROR;
+ }
+
+ if ( val ) {
+ tlog(TL_ALARM,"getsockopt return: %s:%d - %s(%d)",inet_ntoa(cs->serv_addr.sin_addr),
+ ntohs(cs->serv_addr.sin_port), strerror(val), val);
+ shutdown(cs->fd,SHUT_RDWR);
+ close(cs->fd);
+ cs->fd = 0;
+ cs->state = CS_ERROR;
+ return CS_ERROR;
+ }
+
+
+ ling.l_onoff = ling.l_linger = 0;
+ if (setsockopt(cs->fd, SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling))==-1) {
+ tlog(TL_ALARM,"setsockopt: LINGER %s:%d - %s",inet_ntoa(cs->serv_addr.sin_addr), ntohs(cs->serv_addr.sin_port),
+ strerror(errno));
+ shutdown(cs->fd,SHUT_RDWR);
+ close(cs->fd);
+ cs->fd = 0;
+ cs->state = CS_ERROR;
+ return CS_ERROR;
+ }
+ cs->state = CS_CONNECTED;
+ return CS_CONNECTED;
+}
+
u_int32_t
TC_ClientInitConnection(TC_Connection *cs, char *name, u_int32_t port) {
- int flags;
+ int flags, val=1;
cs = TC_fillConnection(cs, name, port);
tlog(TL_CRIT|TL_EXIT,"socket4: %s:%d - %s",inet_ntoa(cs->serv_addr.sin_addr),
ntohs(cs->serv_addr.sin_port),strerror(errno));
+ if (setsockopt(cs->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
+ tlog(TL_CRIT|TL_EXIT, "socketsockopt failed: %s (d%)", strerror(errno), errno);
+ return CS_ERROR;
+ }
+
if ((flags=fcntl(cs->fd,F_GETFL,0)) == -1)
tlog(TL_ALARM,"fcntl F_GETFL - %s",strerror(errno));
if (fcntl(cs->fd,F_SETFL,flags|O_NDELAY) < 0 )
memcpy( &(nc->serv_addr), &cli_addr, clilen );
nc->state = CS_CONNECTED;
+ setlinger(nc);
return nc;
}
TC_Connection *
TC_fillConnection(TC_Connection *sc, char *name, u_int32_t port) {
if ( !sc )
- sc = (TC_Connection *)t0malloc(sizeof(TC_Connection));
+ sc = (TC_Connection *)tmalloc(sizeof(TC_Connection));
+ memset(sc, 0, sizeof(TC_Connection));
sc->serv_addr.sin_family = AF_INET;
sc->serv_addr.sin_addr.s_addr = (name) ? inet_addr(name) : htonl(INADDR_ANY);
sc->serv_addr.sin_port = htons(port);
return sc;
}
-static u_int32_t
-setlinger( TC_Connection *cs ) {
- struct linger ling;
- int val = 0;
- socklen_t size = sizeof(val);
-
- if (getsockopt(cs->fd, SOL_SOCKET,SO_ERROR,&val,&size) == -1) {
- tlog(TL_ALARM,"getsockopt: %s:%d - %s(%d)",inet_ntoa(cs->serv_addr.sin_addr),
- ntohs(cs->serv_addr.sin_port), strerror(errno), errno);
- shutdown(cs->fd,SHUT_RDWR);
- close(cs->fd);
- cs->fd = 0;
- cs->state = CS_ERROR;
- return CS_ERROR;
- }
-
- if ( val ) {
- tlog(TL_ALARM,"getsockopt return: %s:%d - %s(%d)",inet_ntoa(cs->serv_addr.sin_addr),
- ntohs(cs->serv_addr.sin_port), strerror(val), val);
- shutdown(cs->fd,SHUT_RDWR);
- close(cs->fd);
- cs->fd = 0;
- cs->state = CS_ERROR;
- return CS_ERROR;
- }
-
-
- ling.l_onoff = ling.l_linger = 0;
- if (setsockopt(cs->fd, SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling))==-1) {
- tlog(TL_ALARM,"setsockopt: LINGER %s:%d - %s",inet_ntoa(cs->serv_addr.sin_addr),
- strerror(errno));
- shutdown(cs->fd,SHUT_RDWR);
- close(cs->fd);
- cs->fd = 0;
- cs->state = CS_ERROR;
- return CS_ERROR;
- }
- cs->state = CS_CONNECTED;
- return CS_CONNECTED;
-}
u_int32_t
TC_ServerInitConnect( TC_Connection *cs ) {
if (fcntl(cs->fd,F_SETFL,flags|O_NDELAY) < 0 )
tlog(TL_ALARM,"fcntl O_NDELAY - %s",strerror(errno));
+ flags=1;
+ if (setsockopt(cs->fd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)) < 0)
+ tlog(TL_ALARM, "socketsockopt failed: %s (%d)", strerror(errno), errno);
+
if ( connect(cs->fd, (struct sockaddr *) &(cs->serv_addr),
sizeof(struct sockaddr_in)) < 0 ) {
if ( errno == EINPROGRESS || errno == EALREADY ) {
return CS_INPROCESS;
} else if (errno != EISCONN && errno != EALREADY &&
errno != EWOULDBLOCK && errno != EAGAIN) {
- tlog(TL_DEBUG,"open4: %s:%d - %s",
+ tlog(TL_DEBUG,"connect: %s:%d - %s",
inet_ntoa(cs->serv_addr.sin_addr), ntohs(cs->serv_addr.sin_port),
strerror(errno));
shutdown(cs->fd,SHUT_RDWR);
}
cs->state = CS_INPROCESS;
- return TC_ServerConnect( cs );
+ return TC_ServerConnect( cs, 0 );
}
u_int32_t
-TC_ServerConnect( TC_Connection *cs ) {
+TC_ServerConnect( TC_Connection *cs, int timeout ) {
struct pollfd pfd;
int ret;
pfd.fd = cs->fd;
pfd.events = POLLOUT;
pfd.revents = 0;
- ret = poll( &pfd, 1, 0 );
+ ret = poll( &pfd, 1, timeout );
if ( ret<0 ) {
tlog( TL_CRIT, "TC_ServerConnect: poll: %s",
strerror(errno));
int ret,i, fdnum=0;
if ( number==0 || cs ==NULL ) {
+ if (timeout<0)
+ timeout=1000;
usleep( timeout * 1000.0 );
return 0;
}
}
cs[i]->readyio=0;
}
+
+ if ( fdnum==0 ) {
+ tfree(pfd);
+ if (timeout<0)
+ timeout=1000;
+ usleep( timeout * 1000.0 );
+ return 0;
+ }
ret = poll( pfd, fdnum, timeout );
if ( ret<0 ) {
tlog( TL_CRIT, "TC_ReadyIO: poll: %s",
u_int32_t
TC_Talk( TC_Connection *cs ) {
- u_int32_t ret = TC_ServerInitConnect( cs );
+ if ( cs->state==CS_NOTINITED )
+ TC_ServerInitConnect( cs );
- while( ret == CS_INPROCESS ) {
- ret = TC_ServerConnect(cs);
- }
+ while( cs->state == CS_INPROCESS )
+ TC_ServerConnect(cs, 100);
- if ( ret != CS_CONNECTED )
- return ret;
+ if ( cs->state != CS_CONNECTED )
+ return cs->state;
- while( ret != CS_FINISHSEND ) {
- ret = TC_Send(cs);
- if ( ret == CS_ERROR ) return ret;
+ cs->state = CS_SEND;
+ cs->ptr = cs->buf;
+ while( cs->state != CS_FINISHSEND ) {
+ while( !TC_ReadyIO( &cs, 1, 100) );
+ if ( TC_Send(cs) == CS_ERROR ) return CS_ERROR;
}
cs->state = CS_READ;
cs->ptr = cs->buf;
while( cs->state != CS_FINISHREAD ) {
while( !TC_ReadyIO( &cs, 1, 100) );
- if ( ret == CS_ERROR ) return ret;
if ( TC_Read(cs) == CS_ERROR ) return CS_ERROR;
}