X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcpacket.c;h=d2696bbe8c624795fa438aed5b2287ee9f775e6a;hb=96d69ecd5b1e5090db05efee7c992e2b2b1e3062;hp=89e12a476a31a2b588c79a792021eb6c21f3f657;hpb=7a6a74da6c6ad9372bb5a81f2b10f9e4f2bb6e27;p=silc.git diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 89e12a47..d2696bbe 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -306,7 +306,7 @@ static inline SilcBool silc_packet_stream_read(SilcPacketStream ps, inbuf = silc_dlist_get(ps->sc->inbufs); if (!inbuf) { /* Allocate new data input buffer */ - inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE * 61); + inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE * 65); if (!inbuf) { silc_mutex_unlock(ps->lock); return FALSE; @@ -561,7 +561,8 @@ silc_packet_engine_start(SilcRng rng, SilcBool router, if (!engine) return NULL; - engine->contexts = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL, + engine->contexts = silc_hash_table_alloc(NULL, 0, silc_hash_ptr, + NULL, NULL, NULL, silc_packet_engine_context_destr, engine, TRUE); if (!engine->contexts) { @@ -638,7 +639,7 @@ static const char *packet_error[] = { const char *silc_packet_error_string(SilcPacketError error) { if (error < SILC_PACKET_ERR_READ || error > SILC_PACKET_ERR_NO_MEMORY) - return ""; + return ""; return packet_error[error]; } @@ -655,13 +656,28 @@ SilcDList silc_packet_engine_get_streams(SilcPacketEngine engine) silc_mutex_lock(engine->lock); silc_list_start(engine->streams); - while ((ps = silc_list_get(engine->streams))) + while ((ps = silc_list_get(engine->streams))) { + silc_packet_stream_ref(ps); silc_dlist_add(list, ps); + } silc_mutex_unlock(engine->lock); return list; } +/* Free list returned by silc_packet_engine_get_streams */ + +void silc_packet_engine_free_streams_list(SilcDList streams) +{ + SilcPacketStream ps; + + silc_dlist_start(streams); + while ((ps = silc_dlist_get(streams))) + silc_packet_stream_unref(ps); + + silc_dlist_uninit(streams); +} + /* Create new packet stream */ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, @@ -716,7 +732,7 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, ps->sc->schedule = schedule; /* Allocate data input buffer */ - inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE * 61); + inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE * 65); if (!inbuf) { silc_free(ps->sc); ps->sc = NULL; @@ -755,10 +771,10 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, /* If this is UDP stream, allocate UDP remote stream hash table */ if (!engine->udp_remote && silc_socket_stream_is_udp(stream, NULL)) - engine->udp_remote = silc_hash_table_alloc(0, silc_hash_string, NULL, - silc_hash_string_compare, NULL, - silc_packet_engine_hash_destr, - NULL, TRUE); + engine->udp_remote = + silc_hash_table_alloc(NULL, 0, silc_hash_string_case, NULL, + silc_hash_string_case_compare, NULL, + silc_packet_engine_hash_destr, NULL, TRUE); silc_mutex_unlock(engine->lock); @@ -770,6 +786,8 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, return NULL; } + SILC_LOG_DEBUG(("Created packet stream %p", ps)); + return ps; } @@ -872,6 +890,8 @@ void silc_packet_stream_destroy(SilcPacketStream stream) if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0) { stream->destroyed = TRUE; + SILC_LOG_DEBUG(("Marking packet stream %p destroyed", stream)); + /* Close the underlaying stream */ if (!stream->udp && stream->stream) silc_stream_close(stream->stream); @@ -1307,11 +1327,11 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream, if (!src_id && !dst_id) return FALSE; - SILC_LOG_DEBUG(("Setting new IDs to packet stream")); - silc_mutex_lock(stream->lock); if (src_id) { + SILC_LOG_DEBUG(("Setting source ID to packet stream %p", stream)); + silc_free(stream->src_id); if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); @@ -1327,6 +1347,8 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream, } if (dst_id) { + SILC_LOG_DEBUG(("Setting destination ID to packet stream %p", stream)); + silc_free(stream->dst_id); if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); @@ -1352,37 +1374,19 @@ SilcBool silc_packet_get_ids(SilcPacketStream stream, SilcBool *src_id_set, SilcID *src_id, SilcBool *dst_id_set, SilcID *dst_id) { - if (src_id && stream->src_id) { - (*src_id).type = stream->src_id_type; - switch (stream->src_id_type) { - case SILC_ID_CLIENT: - (*src_id).u.client_id = *(SilcClientID *)stream->src_id; - break; - case SILC_ID_SERVER: - (*src_id).u.server_id = *(SilcServerID *)stream->src_id; - break; - case SILC_ID_CHANNEL: - (*src_id).u.channel_id = *(SilcChannelID *)stream->src_id; - break; - } - } + if (src_id && stream->src_id) + if (!silc_id_str2id2(stream->src_id, stream->src_id_len, + stream->src_id_type, src_id)) + return FALSE; + if (stream->src_id && src_id_set) *src_id_set = TRUE; - if (dst_id && stream->dst_id) { - (*dst_id).type = stream->dst_id_type; - switch (stream->dst_id_type) { - case SILC_ID_CLIENT: - (*dst_id).u.client_id = *(SilcClientID *)stream->dst_id; - break; - case SILC_ID_SERVER: - (*dst_id).u.server_id = *(SilcServerID *)stream->dst_id; - break; - case SILC_ID_CHANNEL: - (*dst_id).u.channel_id = *(SilcChannelID *)stream->dst_id; - break; - } - } + if (dst_id && stream->dst_id) + if (!silc_id_str2id2(stream->dst_id, stream->dst_id_len, + stream->dst_id_type, dst_id)) + return FALSE; + if (stream->dst_id && dst_id_set) *dst_id_set = TRUE; @@ -1468,14 +1472,6 @@ static inline void silc_packet_send_ctr_increment(SilcPacketStream stream, unsigned char *iv = silc_cipher_get_iv(cipher); SilcUInt32 pc1, pc2; - /* Increment 64-bit packet counter */ - SILC_GET32_MSB(pc1, iv + 4); - SILC_GET32_MSB(pc2, iv + 8); - if (++pc2 == 0) - ++pc1; - SILC_PUT32_MSB(pc1, iv + 4); - SILC_PUT32_MSB(pc2, iv + 8); - /* Reset block counter */ memset(iv + 12, 0, 4); @@ -1486,17 +1482,30 @@ static inline void silc_packet_send_ctr_increment(SilcPacketStream stream, ret_iv[1] = ret_iv[0] + iv[4]; ret_iv[2] = ret_iv[0] ^ ret_iv[1]; ret_iv[3] = ret_iv[0] + ret_iv[2]; - SILC_PUT32_MSB(pc2, ret_iv + 4); + + /* Increment 32-bit packet counter */ + SILC_GET32_MSB(pc1, iv + 8); + pc1++; + SILC_PUT32_MSB(pc1, ret_iv + 4); + SILC_LOG_HEXDUMP(("IV"), ret_iv, 8); - /* Set new nonce to counter block */ - memcpy(iv + 4, ret_iv, 4); + /* Set new IV to counter block */ + memcpy(iv + 4, ret_iv, 8); + } else { + /* Increment 64-bit packet counter */ + SILC_GET32_MSB(pc1, iv + 4); + SILC_GET32_MSB(pc2, iv + 8); + if (++pc2 == 0) + ++pc1; + SILC_PUT32_MSB(pc1, iv + 4); + SILC_PUT32_MSB(pc2, iv + 8); } SILC_LOG_HEXDUMP(("Counter Block"), iv, 16); } -/* Internal routine to assemble outgoing packet. Assembles and encryptes +/* Internal routine to assemble outgoing packet. Assembles and encrypts the packet. The silc_packet_stream_write needs to be called to send it after this returns TRUE. */ @@ -1605,6 +1614,12 @@ static inline SilcBool silc_packet_send_raw(SilcPacketStream stream, silc_mutex_lock(stream->lock); + if (silc_unlikely(stream->destroyed)) { + SILC_LOG_DEBUG(("Stream %p is destroyed, cannot send packet", stream)); + silc_mutex_unlock(stream->lock); + return FALSE; + } + /* Get packet pointer from the outgoing buffer */ if (silc_unlikely(!silc_packet_send_prepare(stream, truelen + padlen + ivlen + psnlen, hmac, &packet))) { @@ -1973,8 +1988,8 @@ static inline SilcBool silc_packet_parse(SilcPacket packet) silc_buffer_len(buffer)), buffer->head, silc_buffer_headlen(buffer) + silc_buffer_len(buffer)); - SILC_LOG_DEBUG(("Incoming packet type: %d (%s)", packet->type, - silc_get_packet_name(packet->type))); + SILC_LOG_DEBUG(("Incoming packet type: %d (%s), flags %d", packet->type, + silc_get_packet_name(packet->type), packet->flags)); return TRUE; }