/**************************************************************************** Write data to socket. Return TRUE on success. ****************************************************************************/ bool connection_send_data(struct connection *pconn, const unsigned char *data, int len) { if (NULL == pconn || !pconn->used || (is_server() && pconn->server.is_closing)) { return TRUE; } pconn->statistics.bytes_send += len; if (0 < pconn->send_buffer->do_buffer_sends) { flush_connection_send_buffer_packets(pconn); if (!add_connection_data(pconn, data, len)) { log_verbose("cut connection %s due to huge send buffer (1)", conn_description(pconn)); return FALSE; } flush_connection_send_buffer_packets(pconn); } else { flush_connection_send_buffer_all(pconn); if (!add_connection_data(pconn, data, len)) { log_verbose("cut connection %s due to huge send buffer (2)", conn_description(pconn)); return FALSE; } flush_connection_send_buffer_all(pconn); } return TRUE; }
/************************************************************************** write data to socket **************************************************************************/ void send_connection_data(struct connection *pc, const unsigned char *data, int len) { if (pc && pc->used) { pc->statistics.bytes_send += len; if(pc->send_buffer->do_buffer_sends > 0) { flush_connection_send_buffer_packets(pc); if (!add_connection_data(pc, data, len)) { freelog(LOG_ERROR, "cut connection %s due to huge send buffer (1)", conn_description(pc)); } flush_connection_send_buffer_packets(pc); } else { flush_connection_send_buffer_all(pc); if (!add_connection_data(pc, data, len)) { freelog(LOG_ERROR, "cut connection %s due to huge send buffer (2)", conn_description(pc)); } flush_connection_send_buffer_all(pc); } } }
/**************************************************************************** Thaw the connection. Then maybe compress the data waiting to send them to the connection. Returns TRUE on success. See also conn_compression_freeze(). ****************************************************************************/ bool conn_compression_thaw(struct connection *pconn) { #ifdef USE_COMPRESSION pconn->compression.frozen_level--; fc_assert_action_msg(pconn->compression.frozen_level >= 0, pconn->compression.frozen_level = 0, "Too many calls to conn_compression_thaw on %s!", conn_description(pconn)); if (0 == pconn->compression.frozen_level) { return conn_compression_flush(pconn); } #endif /* USE_COMPRESSION */ return pconn->used; }
/************************************************************************** Sanity check packet **************************************************************************/ bool packet_check(struct data_in *din, struct connection *pc) { size_t rem = dio_input_remaining(din); if (rem > 0) { int type, len; dio_input_rewind(din); dio_get_type(din, pc->packet_header.length, &len); dio_get_type(din, pc->packet_header.type, &type); log_packet("received long packet (type %d, len %d, rem %lu) from %s", type, len, (unsigned long) rem, conn_description (pc)); return FALSE; } return TRUE; }
/************************************************************************** ... **************************************************************************/ void check_packet(struct data_in *din, struct connection *pc) { size_t rem = dio_input_remaining(din); if (din->bad_string || din->bad_bit_string || rem != 0) { char from[MAX_LEN_ADDR + MAX_LEN_NAME + 128]; int type, len; assert(pc != NULL); my_snprintf(from, sizeof(from), " from %s", conn_description(pc)); dio_input_rewind(din); dio_get_uint16(din, &len); dio_get_uint8(din, &type); if (din->bad_string) { freelog(LOG_ERROR, "received bad string in packet (type %d, len %d)%s", type, len, from); } if (din->bad_bit_string) { freelog(LOG_ERROR, "received bad bit string in packet (type %d, len %d)%s", type, len, from); } if (din->too_short) { freelog(LOG_ERROR, "received short packet (type %d, len %d)%s", type, len, from); } if (rem > 0) { /* This may be ok, eg a packet from a newer version with extra info * which we should just ignore */ freelog(LOG_VERBOSE, "received long packet (type %d, len %d, rem %lu)%s", type, len, (unsigned long)rem, from); } } }
/**************************************************************************** Default 'conn_close_fn_t' to close a connection. ****************************************************************************/ static void default_conn_close_callback(struct connection *pconn) { fc_assert_msg(conn_close_callback != default_conn_close_callback, "Closing a socket (%s) before calling " "close_socket_set_callback().", conn_description(pconn)); }