예제 #1
0
static tr_tristate_t
receiveresponse( tr_http_t * http )
{
    int    ret, before;
    void * newbuf;

    if( 0 == http->date )
    {
        http->date = tr_date();
    }

    before = http->header.used;
    for(;;)
    {
        if( http->header.size - http->header.used < HTTP_BUFSIZE )
        {
            newbuf = realloc( http->header.buf,
                              http->header.size + HTTP_BUFSIZE );
            if( NULL == newbuf )
            {
                return TR_ERROR;
            }
            http->header.buf = newbuf;
            http->header.size += HTTP_BUFSIZE;
        }

        ret = tr_netRecv( http->sock,
                          (uint8_t *) ( http->header.buf + http->header.used ),
                          http->header.size - http->header.used );
        if( ret & TR_NET_CLOSE )
        {
            checklength( http );
            return TR_OK;
        }
        else if( ret & TR_NET_BLOCK )
        {
            break;
        }
        else
        {
            http->header.used += ret;
        }
    }

    if( before < http->header.used && checklength( http ) )
    {
        return TR_OK;
    }

    if( tr_date() > HTTP_TIMEOUT + http->date )
    {
        return TR_ERROR;
    }

    return TR_WAIT;
}
/* reads a line from fp, and checks its length */
char *getline(FILE *fp){
    static char line[MAXLINE];

    if( fgets(line, MAXLINE, fp) != '\0'){ /* EOF */
        checklength(line);
    }
    return(line);
}
예제 #3
0
파일: route.c 프로젝트: meshlink/meshlink
void route(meshlink_handle_t *mesh, node_t *source, vpn_packet_t *packet) {
	// TODO: route on name or key

	node_t *owner = NULL;
	node_t *via = NULL;
	meshlink_packethdr_t *hdr = (meshlink_packethdr_t *) packet->data;
	owner = lookup_node(mesh, (char *)hdr->destination);
	logger(mesh, MESHLINK_DEBUG, "Routing packet from \"%s\" to \"%s\"\n", hdr->source, hdr->destination);

	//Check Lenght
	if(!checklength(source, packet, sizeof *hdr))
		return;

	if(owner == NULL) {
		//Lookup failed
		logger(mesh, MESHLINK_WARNING, "Cant lookup the owner of a packet in the route() function. This should never happen!\n");
		logger(mesh, MESHLINK_WARNING, "Destination was: %s\n", hdr->destination);
		return;
	}

	if(owner == mesh->self) {
		const void *payload = packet->data + sizeof *hdr;
		size_t len = packet->len - sizeof *hdr;

		char hex[len*2 + 1];
		if(mesh->log_level >= MESHLINK_DEBUG)
			bin2hex(payload, hex, len);	// don't do this unless it's going to be logged
		logger(mesh, MESHLINK_DEBUG, "I received a packet for me with payload: %s\n", hex);

		if(mesh->receive_cb)
			mesh->receive_cb(mesh, (meshlink_node_t *)source, payload, len);
		return;
	}

	if(!owner->status.reachable) {
		//TODO: check what to do here, not just print a warning
		logger(mesh, MESHLINK_WARNING, "The owner of a packet in the route() function is unreachable. Dropping packet.\n");
		return;
	}

	via = (owner->via == mesh->self) ? owner->nexthop : owner->via;
	if(via == source) {
		logger(mesh, MESHLINK_ERROR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
		return;
	}

	send_packet(mesh, owner, packet);
	return;
}
예제 #4
0
static int
checklength( tr_http_t * http )
{
    char * buf;
    int    num, ii, len, lastnum;

    switch( http->lengthtype )
    {
        case HTTP_LENGTH_UNKNOWN:
            if( learnlength( http ) )
            {
                return checklength( http );
            }
            break;

        case HTTP_LENGTH_EOF:
            break;

        case HTTP_LENGTH_FIXED:
            if( http->header.used >= http->chunkoff + http->chunklen )
            {
                http->header.used = http->chunkoff + http->chunklen;
                return 1;
            }
            break;

        case HTTP_LENGTH_CHUNKED:
            buf     = http->header.buf;
            lastnum = -1;
            while( http->header.used > http->chunkoff + http->chunklen )
            {
                num = http->chunkoff + http->chunklen;
                if( lastnum == num )
                {
                    /* ugh, some trackers send Transfer-encoding: chunked
                       and then don't encode the body */
                    http->lengthtype = HTTP_LENGTH_EOF;
                    return checklength( http );
                }
                lastnum = num;
                while(  http->header.used > num && NL( buf[num] ) )
                {
                    num++;
                }
                ii = num;
                while( http->header.used > ii && !NL( buf[ii] ) )
                {
                    ii++;
                }
                if( http->header.used > ii )
                {
                    /* strtol should stop at the newline */
                    len = strtol( buf + num, NULL, 16 );
                    if( 0 == len )
                    {
                        /* XXX should handle invalid length
                               differently than 0 length chunk */
                        http->header.used = http->chunkoff + http->chunklen;
                        return 1;
                    }
                    if( http->header.used > ii + 1 )
                    {
                        ii += ( 0 == memcmp( buf + ii, CR LF, 2 ) ? 2 : 1 );
                        if( http->header.used > ii )
                        {
                            memmove( buf + http->chunkoff + http->chunklen,
                                     buf + ii, http->header.used - ii );
                        }
                        http->header.used -=
                            ii - ( http->chunkoff + http->chunklen );
                        http->chunkoff += http->chunklen;
                        http->chunklen = len;
                    }
                }
            }
            break;
    }

    return 0;
}