int fetch_from_buf(char *string, int string_len,
char **buf, int *buflen, int *buf_datalen) {
- /* if there are string_len bytes in buf, write them onto string,
+ /* There must be string_len bytes in buf; write them onto string,
* then memmove buf back (that is, remove them from buf).
*
- * If there are not enough bytes on the buffer to fill string, return -1.
- *
* Return the number of bytes still on the buffer. */
assert(string && buf && *buf && buflen && buf_datalen);
+ assert(string_len <= *buf_datalen); /* make sure we don't ask for too much */
- /* this is the point where you would grow the buffer, if you want to */
-
- if(string_len > *buf_datalen) /* we want too much. sorry. */
- return -1;
-
memcpy(string,*buf,string_len);
*buf_datalen -= string_len;
memmove(*buf, *buf+string_len, *buf_datalen);
cell.length = amount_to_process;
}
- if(connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE,
- cell.length, conn) < 0)
- return -1;
+ connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE, cell.length, conn);
circ = circuit_get_by_conn(conn);
if(!circ) {
if(conn->inbuf_datalen < CELL_NETWORK_SIZE) /* entire response available? */
return 0; /* not yet */
- if(connection_fetch_from_buf(crypted,CELL_NETWORK_SIZE,conn) < 0) {
- return -1;
- }
+ connection_fetch_from_buf(crypted,CELL_NETWORK_SIZE,conn);
#if 0
printf("Cell header crypttext: ");
if(conn->inbuf_datalen < sizeof(socks4_t)) /* basic info available? */
return 0; /* not yet */
- if(connection_fetch_from_buf((char *)&socks4_info,sizeof(socks4_t),conn) < 0)
- return -1;
+ connection_fetch_from_buf((char *)&socks4_info,sizeof(socks4_t),conn);
log_fn(LOG_DEBUG,"Successfully read socks info.");
ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
return -1;
}
- if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
- return -1;
+ connection_fetch_from_buf(tmpbuf,amt,conn);
conn->read_username = 1;
log_fn(LOG_DEBUG,"Successfully read username.");
}
ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
return -1;
}
- if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
- return -1;
+ connection_fetch_from_buf(tmpbuf,amt,conn);
conn->dest_addr = strdup(tmpbuf);
log_fn(LOG_NOTICE,"successfully read dest addr '%s'",
if(conn->inbuf_datalen < 128) /* entire response available? */
return 0; /* not yet */
- if(connection_fetch_from_buf(cipher,128,conn) < 0) {
- return -1;
- }
+ connection_fetch_from_buf(cipher,128,conn);
log(LOG_DEBUG,"or_handshake_client_process_auth() : Received auth.");
/* decrypt response */
if(conn->inbuf_datalen < 128) /* entire response available? */
return 0; /* not yet */
- if(connection_fetch_from_buf(cipher,128,conn) < 0) {
- return -1;
- }
+ connection_fetch_from_buf(cipher,128,conn);
log(LOG_DEBUG,"or_handshake_server_process_auth() : Received auth.");
/* decrypt response */
if(conn->inbuf_datalen < 128) /* entire response available? */
return 0; /* not yet */
- if(connection_fetch_from_buf(cipher,128,conn) < 0) {
- return -1;
- }
+ connection_fetch_from_buf(cipher,128,conn);
log(LOG_DEBUG,"or_handshake_server_process_nonce() : Received auth.");
/* decrypt response */
return 0; /* not yet */
}
- if(connection_fetch_from_buf(buf,strlen(getstring),conn) < 0) {
- return -1;
- }
+ connection_fetch_from_buf(buf,strlen(getstring),conn);
if(strncasecmp(buf,getstring,strlen("GET / HTTP/"))) {
log_fn(LOG_DEBUG,"Command doesn't seem to be a get. Closing,");
if(amt < 0) /* not there yet */
return 0;
headers = tor_malloc(amt+1);
- if(connection_fetch_from_buf(headers,amt,conn) < 0) {
- log_fn(LOG_DEBUG,"fetch_from_buf failed (reading headers).");
- return -1;
- }
+ connection_fetch_from_buf(headers,amt,conn);
headers[amt] = 0; /* null terminate it, */
free(headers); /* and then throw it away */
reading_headers = 0;
log_fn(LOG_DEBUG,"Pulling %d bytes in at offset %d.",
amt, directorylen);
- if(connection_fetch_from_buf(the_directory+directorylen,amt,conn) < 0) {
- log_fn(LOG_DEBUG,"fetch_from_buf failed (reading dir).");
- return -1;
- }
+ connection_fetch_from_buf(the_directory+directorylen,amt,conn);
directorylen += amt;
#define MAX_DNSWORKERS 50
#define MIN_DNSWORKERS 3
+#define MAX_IDLE_DNSWORKERS 10
int num_workers=0;
int num_workers_busy=0;
static int dns_assign_to_worker(connection_t *exitconn) {
connection_t *dnsconn;
unsigned char len;
- struct hostent *rent;
spawn_enough_workers(); /* respawn here, to be sure there are enough */
dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER, DNSWORKER_STATE_IDLE);
if(!dnsconn) {
- log(LOG_INFO,"dns_assign_to_worker(): no idle dns workers. Doing it myself.");
-
- /* short version which does it all right here */
- rent = gethostbyname(exitconn->address);
- if (!rent) {
- return dns_found_answer(exitconn->address, 0);
- }
- return dns_found_answer(exitconn->address, *(uint32_t *)rent->h_addr);
+ log(LOG_INFO,"dns_assign_to_worker(): no idle dns workers. Failing.");
+ return -1;
}
dnsconn->address = strdup(exitconn->address);
return 0; /* not yet */
assert(conn->inbuf_datalen == 4);
- if(connection_fetch_from_buf((char*)&answer,sizeof(answer),conn) < 0) {
- log(LOG_ERR,"connection_dnsworker_process_inbuf(): Broken inbuf. Worker dying.");
- /* XXX exitconn's never going to get his answer :( */
- return -1;
- }
+ connection_fetch_from_buf((char*)&answer,sizeof(answer),conn);
dns_found_answer(conn->address, answer);
static void spawn_enough_workers(void) {
int num_workers_needed; /* aim to have 1 more than needed,
* but no less than min and no more than max */
+ connection_t *dnsconn;
+
+ if(num_workers_busy == MAX_DNSWORKERS) {
+ /* We always want at least one worker idle.
+ * So find the oldest busy worker and kill it.
+ */
+
+ }
if(num_workers_busy >= MIN_DNSWORKERS)
num_workers_needed = num_workers_busy+1;
num_workers++;
}
- /* FFFF this is where we will cull extra workers */
+ while(num_workers > num_workers_needed+MAX_IDLE_DNSWORKERS) { /* too many idle? */
+ /* cull excess workers */
+ dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER, DNSWORKER_STATE_IDLE);
+ assert(dnsconn);
+ dnsconn->marked_for_close = 1;
+ num_workers--;
+ }
}
/*
test_memeq(str+10,buf,246);
test_eq(buf_datalen,246);
- test_eq(-1, fetch_from_buf(str2, 247, &buf, &buflen, &buf_datalen));
- test_memeq(str+10,buf,246);
- test_eq(buf_datalen, 246);
-
test_eq(0, fetch_from_buf(str2, 246, &buf, &buflen, &buf_datalen));
test_memeq(str2, str+10, 246);
test_eq(buflen,MAX_BUF_SIZE);