refactor so connection_write_to_buf() never fails

svn:r537
This commit is contained in:
Roger Dingledine 2003-10-04 02:38:18 +00:00
parent a6bab569ab
commit f563bbd2f9
10 changed files with 39 additions and 72 deletions

View File

@ -267,7 +267,8 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
} }
log_fn(LOG_DEBUG,"Passing on unrecognized cell."); log_fn(LOG_DEBUG,"Passing on unrecognized cell.");
return connection_write_cell_to_buf(cell, conn); connection_write_cell_to_buf(cell, conn);
return 0;
} }
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction, int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
@ -737,9 +738,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
return -1; return -1;
} }
if(connection_write_cell_to_buf(&cell, circ->n_conn) < 0) { connection_write_cell_to_buf(&cell, circ->n_conn);
return -1;
}
circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
circ->state = CIRCUIT_STATE_BUILDING; circ->state = CIRCUIT_STATE_BUILDING;
@ -843,10 +842,7 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6, DH_ONIONSKIN_LEN); memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6, DH_ONIONSKIN_LEN);
if(connection_write_cell_to_buf(&newcell, circ->n_conn) < 0) { connection_write_cell_to_buf(&newcell, circ->n_conn);
return -1;
}
return 0; return 0;
} }

View File

@ -489,13 +489,10 @@ int connection_handle_write(connection_t *conn) {
return 0; return 0;
} }
int connection_write_to_buf(const char *string, int len, connection_t *conn) { void connection_write_to_buf(const char *string, int len, connection_t *conn) {
if(!len) if(!len || conn->marked_for_close)
return 0; return;
if(conn->marked_for_close)
return 0;
if( (!connection_speaks_cells(conn)) || if( (!connection_speaks_cells(conn)) ||
(!connection_state_is_open(conn)) || (!connection_state_is_open(conn)) ||
@ -506,7 +503,10 @@ int connection_write_to_buf(const char *string, int len, connection_t *conn) {
conn->outbuf_flushlen += len; conn->outbuf_flushlen += len;
} }
return write_to_buf(string, len, conn->outbuf); if(write_to_buf(string, len, conn->outbuf) < 0) {
log_fn(LOG_WARNING,"write_to_buf failed. Closing connection (fd %d).", conn->s);
conn->marked_for_close = 1;
}
} }
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) { connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) {
@ -653,7 +653,8 @@ int connection_send_destroy(aci_t aci, connection_t *conn) {
cell.aci = aci; cell.aci = aci;
cell.command = CELL_DESTROY; cell.command = CELL_DESTROY;
log_fn(LOG_INFO,"Sending destroy (aci %d).",aci); log_fn(LOG_INFO,"Sending destroy (aci %d).",aci);
return connection_write_cell_to_buf(&cell, conn); connection_write_cell_to_buf(&cell, conn);
return 0;
} }
int connection_process_inbuf(connection_t *conn) { int connection_process_inbuf(connection_t *conn) {

View File

@ -171,13 +171,9 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
// printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE); // printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE);
stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE); stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE);
if(connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE, connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
cell->length - RELAY_HEADER_SIZE, conn) < 0) { cell->length - RELAY_HEADER_SIZE, conn);
/*ENDCLOSE*/ conn->marked_for_close = 1; connection_consider_sending_sendme(conn, edge_type);
return 0;
}
if(connection_consider_sending_sendme(conn, edge_type) < 0)
/*ENDCLOSE*/ conn->marked_for_close = 1;
return 0; return 0;
case RELAY_COMMAND_END: case RELAY_COMMAND_END:
if(!conn) { if(!conn) {
@ -302,7 +298,8 @@ int connection_edge_finished_flushing(connection_t *conn) {
case AP_CONN_STATE_OPEN: case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN:
connection_stop_writing(conn); connection_stop_writing(conn);
return connection_consider_sending_sendme(conn, conn->type); connection_consider_sending_sendme(conn, conn->type);
return 0;
case AP_CONN_STATE_SOCKS_WAIT: case AP_CONN_STATE_SOCKS_WAIT:
connection_stop_writing(conn); connection_stop_writing(conn);
return 0; return 0;
@ -403,18 +400,18 @@ repeat_connection_package_raw_inbuf:
goto repeat_connection_package_raw_inbuf; goto repeat_connection_package_raw_inbuf;
} }
int connection_consider_sending_sendme(connection_t *conn, int edge_type) { void connection_consider_sending_sendme(connection_t *conn, int edge_type) {
circuit_t *circ; circuit_t *circ;
cell_t cell; cell_t cell;
if(connection_outbuf_too_full(conn)) if(connection_outbuf_too_full(conn))
return 0; return;
circ = circuit_get_by_conn(conn); circ = circuit_get_by_conn(conn);
if(!circ) { if(!circ) {
/* this can legitimately happen if the destroy has already arrived and torn down the circuit */ /* this can legitimately happen if the destroy has already arrived and torn down the circuit */
log_fn(LOG_INFO,"No circuit associated with conn. Skipping."); log_fn(LOG_INFO,"No circuit associated with conn. Skipping.");
return 0; return;
} }
memset(&cell, 0, sizeof(cell_t)); memset(&cell, 0, sizeof(cell_t));
@ -434,11 +431,9 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) { if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
log_fn(LOG_WARNING,"circuit_deliver_relay_cell failed. Closing."); log_fn(LOG_WARNING,"circuit_deliver_relay_cell failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return;
} }
} }
return 0;
} }
static int connection_ap_handshake_process_socks(connection_t *conn) { static int connection_ap_handshake_process_socks(connection_t *conn) {

View File

@ -248,13 +248,13 @@ static int connection_tls_finish_handshake(connection_t *conn) {
/* ********************************** */ /* ********************************** */
int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) { void connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
char networkcell[CELL_NETWORK_SIZE]; char networkcell[CELL_NETWORK_SIZE];
char *n = networkcell; char *n = networkcell;
cell_pack(n, cellp); cell_pack(n, cellp);
return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn); connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
} }
/* if there's a whole cell there, pull it off and process it. */ /* if there's a whole cell there, pull it off and process it. */

View File

@ -267,13 +267,9 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
cpuworker->state = CPUWORKER_STATE_BUSY_ONION; cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
num_cpuworkers_busy++; num_cpuworkers_busy++;
if(connection_write_to_buf(&question_type, 1, cpuworker) < 0 || connection_write_to_buf(&question_type, 1, cpuworker);
connection_write_to_buf(tag, sizeof(tag), cpuworker) < 0 || connection_write_to_buf(tag, sizeof(tag), cpuworker);
connection_write_to_buf(circ->onionskin, DH_ONIONSKIN_LEN, cpuworker) < 0) { connection_write_to_buf(circ->onionskin, DH_ONIONSKIN_LEN, cpuworker);
log_fn(LOG_WARNING,"Write failed. Closing worker and failing circ.");
cpuworker->marked_for_close = 1;
return -1;
}
} }
return 0; return 0;
} }

View File

@ -90,10 +90,7 @@ static int directory_send_command(connection_t *conn, int command) {
switch(command) { switch(command) {
case DIR_CONN_STATE_CONNECTING_FETCH: case DIR_CONN_STATE_CONNECTING_FETCH:
if(connection_write_to_buf(fetchstring, strlen(fetchstring), conn) < 0) { connection_write_to_buf(fetchstring, strlen(fetchstring), conn);
log_fn(LOG_WARNING,"Couldn't write fetch to buffer.");
return -1;
}
conn->state = DIR_CONN_STATE_CLIENT_SENDING_FETCH; conn->state = DIR_CONN_STATE_CLIENT_SENDING_FETCH;
break; break;
case DIR_CONN_STATE_CONNECTING_UPLOAD: case DIR_CONN_STATE_CONNECTING_UPLOAD:
@ -104,10 +101,7 @@ static int directory_send_command(connection_t *conn, int command) {
} }
snprintf(tmp, sizeof(tmp), "POST / HTTP/1.0\r\nContent-Length: %d\r\n\r\n%s", snprintf(tmp, sizeof(tmp), "POST / HTTP/1.0\r\nContent-Length: %d\r\n\r\n%s",
strlen(s), s); strlen(s), s);
if(connection_write_to_buf(tmp, strlen(tmp), conn) < 0) { connection_write_to_buf(tmp, strlen(tmp), conn);
log_fn(LOG_WARNING,"Couldn't write post/descriptor to buffer.");
return -1;
}
conn->state = DIR_CONN_STATE_CLIENT_SENDING_UPLOAD; conn->state = DIR_CONN_STATE_CLIENT_SENDING_UPLOAD;
break; break;
} }
@ -200,11 +194,8 @@ static int directory_handle_command(connection_t *conn) {
} }
log_fn(LOG_DEBUG,"Dumping directory to client."); log_fn(LOG_DEBUG,"Dumping directory to client.");
if((connection_write_to_buf(answerstring, strlen(answerstring), conn) < 0) || connection_write_to_buf(answerstring, strlen(answerstring), conn);
(connection_write_to_buf(cp, dlen, conn) < 0)) { connection_write_to_buf(cp, dlen, conn);
log_fn(LOG_WARNING,"Failed to write answerstring+directory to outbuf.");
return -1;
}
conn->state = DIR_CONN_STATE_SERVER_WRITING; conn->state = DIR_CONN_STATE_SERVER_WRITING;
return 0; return 0;
} }
@ -218,10 +209,7 @@ static int directory_handle_command(connection_t *conn) {
return -1; /* XXX should write an http failed code */ return -1; /* XXX should write an http failed code */
} }
dirserv_get_directory(&cp); /* rebuild and write to disk */ dirserv_get_directory(&cp); /* rebuild and write to disk */
if(connection_write_to_buf(answerstring, strlen(answerstring), conn) < 0) { connection_write_to_buf(answerstring, strlen(answerstring), conn);
log_fn(LOG_WARNING,"Failed to write answerstring to outbuf.");
return -1;
}
conn->state = DIR_CONN_STATE_SERVER_WRITING; conn->state = DIR_CONN_STATE_SERVER_WRITING;
return 0; return 0;
} }

View File

@ -170,14 +170,8 @@ static int assign_to_dnsworker(connection_t *exitconn) {
num_dnsworkers_busy++; num_dnsworkers_busy++;
len = strlen(dnsconn->address); len = strlen(dnsconn->address);
/* FFFF we should have it retry if the first worker bombs out */ connection_write_to_buf(&len, 1, dnsconn);
if(connection_write_to_buf(&len, 1, dnsconn) < 0 || connection_write_to_buf(dnsconn->address, len, dnsconn);
connection_write_to_buf(dnsconn->address, len, dnsconn) < 0) {
log_fn(LOG_WARNING,"Write failed. Closing worker and failing resolve.");
dnsconn->marked_for_close = 1;
dns_cancel_pending_resolve(exitconn->address, NULL);
return -1;
}
// log_fn(LOG_DEBUG,"submitted '%s'", exitconn->address); // log_fn(LOG_DEBUG,"submitted '%s'", exitconn->address);
return 0; return 0;

View File

@ -345,8 +345,7 @@ static int prepare_for_poll(void) {
conn->address, conn->port); conn->address, conn->port);
memset(&cell,0,sizeof(cell_t)); memset(&cell,0,sizeof(cell_t));
cell.command = CELL_PADDING; cell.command = CELL_PADDING;
if(connection_write_cell_to_buf(&cell, conn) < 0) connection_write_cell_to_buf(&cell, conn);
conn->marked_for_close = 1;
} }
} }
} }

View File

@ -151,9 +151,7 @@ int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *key
return -1; return -1;
} }
if(connection_write_cell_to_buf(&cell, circ->p_conn) < 0) { connection_write_cell_to_buf(&cell, circ->p_conn);
return -1;
}
log_fn(LOG_DEBUG,"Finished sending 'created' cell."); log_fn(LOG_DEBUG,"Finished sending 'created' cell.");
return 0; return 0;

View File

@ -550,7 +550,7 @@ int connection_wants_to_flush(connection_t *conn);
int connection_outbuf_too_full(connection_t *conn); int connection_outbuf_too_full(connection_t *conn);
int connection_flush_buf(connection_t *conn); int connection_flush_buf(connection_t *conn);
int connection_handle_write(connection_t *conn); int connection_handle_write(connection_t *conn);
int connection_write_to_buf(const char *string, int len, connection_t *conn); void connection_write_to_buf(const char *string, int len, connection_t *conn);
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port); connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port);
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port); connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
@ -581,7 +581,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
int connection_edge_finished_flushing(connection_t *conn); int connection_edge_finished_flushing(connection_t *conn);
int connection_package_raw_inbuf(connection_t *conn); int connection_package_raw_inbuf(connection_t *conn);
int connection_consider_sending_sendme(connection_t *conn, int edge_type); void connection_consider_sending_sendme(connection_t *conn, int edge_type);
int connection_exit_connect(connection_t *conn); int connection_exit_connect(connection_t *conn);
@ -601,7 +601,7 @@ connection_t *connection_or_connect(routerinfo_t *router);
int connection_tls_start_handshake(connection_t *conn, int receiving); int connection_tls_start_handshake(connection_t *conn, int receiving);
int connection_tls_continue_handshake(connection_t *conn); int connection_tls_continue_handshake(connection_t *conn);
int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn); void connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn);
int connection_process_cell_from_inbuf(connection_t *conn); int connection_process_cell_from_inbuf(connection_t *conn);
/********************************* cpuworker.c *****************************/ /********************************* cpuworker.c *****************************/