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);
+ tlog(TL_CRIT|TL_EXIT, "socketsockopt failed: %s (%d)", strerror(errno), errno);
return CS_ERROR;
}
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_addr.s_addr = (name && *name != '*' ) ? inet_addr(name) : htonl(INADDR_ANY);
+ if ( sc->serv_addr.sin_addr.s_addr == INADDR_NONE ) {
+ struct hostent *host;
+
+ /*
+ * Can't parse address: it's a DNS Name
+ */
+ host = gethostbyname(name);
+ if ( host && host->h_addrtype == AF_INET ) {
+ memcpy(&sc->serv_addr.sin_addr.s_addr, host->h_addr_list[0],
+ sizeof(&sc->serv_addr.sin_addr.s_addr));
+ } else {
+ tlog(TL_CRIT,"gethostbyname: %s - %s", name, hstrerror(h_errno));
+ sc->state = CS_ERROR;
+ return sc;
+ }
+ }
+
sc->serv_addr.sin_port = htons(port);
sc->state = CS_NOTINITED;
return sc;
if ( cs->state == CS_ERROR )
return CS_ERROR;
- if ( cs->state != CS_SEND ) {
+ if ( cs->state != CS_SEND || cs->ptr == NULL ) {
cs->state = CS_SEND;
- cs->ptr = cs->buf;
+ cs->ptr = (char*)cs->buf;
+ cs->len = cs->buf->len;
+
+ /* convert fields to network byteorder */
+ cs->buf->len = htonl(cs->buf->len);
+ cs->buf->type = htonl(cs->buf->type);
}
- if ( cs->ptr - cs->buf >= cs->len ) {
+ if ( cs->ptr - (char*)cs->buf >= cs->len ) {
cs->state = CS_FINISHSEND;
return CS_FINISHSEND;
}
- if ((sz=write(cs->fd, cs->ptr, cs->len - (cs->ptr - cs->buf)))==0 ||
+ if ((sz=write(cs->fd, cs->ptr, cs->len - (cs->ptr - (char*)cs->buf)))==0 ||
(sz < 0 && (errno == EWOULDBLOCK || errno == EAGAIN))) {
/* SunOS 4.1.x, are broken and select() says that
cs->ptr += sz;
- if ( cs->ptr - cs->buf >= cs->len ) {
+ if ( cs->ptr - (char*)cs->buf >= cs->len ) {
cs->state = CS_FINISHSEND;
+ /* revert byteorder conversion */
+ cs->buf->len = ntohl(cs->buf->len);
+ cs->buf->type = ntohl(cs->buf->type);
return CS_FINISHSEND;
}
static void
resizeCS( TC_Connection *cs, int sz ) {
- int diff = cs->ptr - cs->buf;
+ int diff = cs->ptr - (char*)cs->buf;
+
if ( cs->len >= sz )
return;
cs->len = sz;
- cs->buf = (char*)trealloc( (void*)cs->buf, cs->len );
- cs->ptr = cs->buf + diff;
+ cs->buf = (TCMsg*)trealloc( (void*)cs->buf, cs->len );
+ cs->ptr = ((char*)cs->buf) + diff;
}
u_int32_t
-TC_Read( TC_Connection *cs ) {
+TC_Read( TC_Connection *cs, size_t maxsize ) {
int sz, totalread = -1, toread=0, alreadyread;
if ( cs->state == CS_ERROR )
return CS_ERROR;
- if (cs->state != CS_READ ) {
+ if (cs->state != CS_READ || cs->ptr == NULL ) {
cs->state = CS_READ;
- cs->ptr = cs->buf;
+ cs->ptr = (char*)cs->buf;
+ cs->len = 0;
}
- alreadyread = cs->ptr - cs->buf;
- if ( alreadyread < sizeof(u_int32_t) ) {
- toread = sizeof(u_int32_t) - alreadyread;
- resizeCS(cs, sizeof(u_int32_t));
+ alreadyread = cs->ptr - (char*)cs->buf;
+ if ( alreadyread < TCMSGHDRSZ ) {
+ toread = TCMSGHDRSZ - alreadyread;
+ resizeCS(cs, TCMSGHDRSZ);
} else {
- totalread = *(u_int32_t*)(cs->buf);
+ totalread = ntohl(cs->buf->len);
+ if ( maxsize > 0 && totalread > maxsize )
+ {
+ tlog(TL_ALARM,"TC_Read: message size (%d b) is greater than max allowed (%d b)", totalread, maxsize);
+ cs->state = CS_ERROR;
+ return CS_ERROR;
+ }
toread = totalread - alreadyread;
if ( toread == 0 ) {
cs->state = CS_FINISHREAD;
return CS_ERROR;
}
-
+ if ( alreadyread < TCMSGHDRSZ && alreadyread + sz >= TCMSGHDRSZ ) {
+ /*
+ * we just read header - we can get totalread value.
+ */
+ totalread = ntohl(cs->buf->len);
+ }
+
cs->ptr += sz;
alreadyread += sz;
if ( sz == 0 && alreadyread != totalread ) {
cs->state = CS_ERROR;
return CS_ERROR;
}
- cs->state = ( alreadyread == totalread ) ? CS_FINISHREAD : CS_READ;
+
+ if ( alreadyread == totalread ) {
+ cs->buf->len = ntohl(cs->buf->len);
+ cs->buf->type = ntohl(cs->buf->type);
+ cs->state = CS_FINISHREAD;
+ }
+
return cs->state;
}
}
u_int32_t
-TC_Talk( TC_Connection *cs ) {
+TC_Talk( TC_Connection *cs, size_t maxsize ) {
if ( cs->state==CS_NOTINITED )
TC_ServerInitConnect( cs );
return cs->state;
cs->state = CS_SEND;
- cs->ptr = cs->buf;
+ cs->ptr = NULL;
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;
+ cs->ptr = NULL;
while( cs->state != CS_FINISHREAD ) {
while( !TC_ReadyIO( &cs, 1, 100) );
- if ( TC_Read(cs) == CS_ERROR ) return CS_ERROR;
+ if ( TC_Read(cs, maxsize) == CS_ERROR ) return CS_ERROR;
}
return CS_OK;