X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=tcp.c;h=a9295e400200b9bf98c790d28d42826c900961d8;hb=e72b58a0470edb0b592699c1f47fc5b27cdf1e4f;hp=ecc3bf1c1a8a64ba1533b3b8fc0c9725b2697446;hpb=36a3bf04b749bbb580b33288b84fb197f97285c6;p=tedtools.git diff --git a/tcp.c b/tcp.c index ecc3bf1..a9295e4 100644 --- a/tcp.c +++ b/tcp.c @@ -105,7 +105,7 @@ TC_ClientInitConnection(TC_Connection *cs, char *name, u_int32_t port) { 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; } @@ -159,7 +159,24 @@ TC_fillConnection(TC_Connection *sc, char *name, u_int32_t port) { 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; @@ -322,17 +339,22 @@ TC_Send( TC_Connection *cs ) { 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 @@ -354,8 +376,11 @@ TC_Send( TC_Connection *cs ) { 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; } @@ -364,32 +389,40 @@ TC_Send( TC_Connection *cs ) { 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; @@ -408,7 +441,13 @@ TC_Read( TC_Connection *cs ) { 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 ) { @@ -416,7 +455,13 @@ TC_Read( TC_Connection *cs ) { 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; } @@ -437,7 +482,7 @@ TC_FreeConnection( TC_Connection *cs ) { } u_int32_t -TC_Talk( TC_Connection *cs ) { +TC_Talk( TC_Connection *cs, size_t maxsize ) { if ( cs->state==CS_NOTINITED ) TC_ServerInitConnect( cs ); @@ -448,17 +493,17 @@ TC_Talk( TC_Connection *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;