diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-07-07 13:31:07 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-08-08 15:41:02 +0200 |
commit | 05a2a7950cb5ea440b41882da05f1eae280ba979 (patch) | |
tree | 3295b09feb86686d6bbb4a700fa051891253a532 /src/libipsec | |
parent | ec486e9433320c425f6a31c7290ad7a806818ec2 (diff) | |
download | strongswan-05a2a7950cb5ea440b41882da05f1eae280ba979.tar.bz2 strongswan-05a2a7950cb5ea440b41882da05f1eae280ba979.tar.xz |
esp_packet_t implements packet_t interface
This should allow to avoid unnecessary cloning of packet data.
Diffstat (limited to 'src/libipsec')
-rw-r--r-- | src/libipsec/esp_packet.c | 142 | ||||
-rw-r--r-- | src/libipsec/esp_packet.h | 24 |
2 files changed, 100 insertions, 66 deletions
diff --git a/src/libipsec/esp_packet.c b/src/libipsec/esp_packet.c index 193bc621d..75d8a7a94 100644 --- a/src/libipsec/esp_packet.c +++ b/src/libipsec/esp_packet.c @@ -40,14 +40,9 @@ struct private_esp_packet_t { esp_packet_t public; /** - * Source address + * Raw ESP packet */ - host_t *src; - - /** - * Destination address - */ - host_t *dst; + packet_t *packet; /** * Payload of this packet @@ -59,19 +54,73 @@ struct private_esp_packet_t { */ u_int8_t next_header; - /** - * Raw packet data - */ - chunk_t packet_data; }; +/** + * Forward declaration for clone() + */ +static private_esp_packet_t *esp_packet_create_empty(packet_t *packet); + +METHOD(packet_t, set_source, void, + private_esp_packet_t *this, host_t *src) +{ + return this->packet->set_source(this->packet, src); +} + +METHOD2(esp_packet_t, packet_t, get_source, host_t*, + private_esp_packet_t *this) +{ + return this->packet->get_source(this->packet); +} + +METHOD(packet_t, set_destination, void, + private_esp_packet_t *this, host_t *dst) +{ + return this->packet->set_destination(this->packet, dst); +} + +METHOD2(esp_packet_t, packet_t, get_destination, host_t*, + private_esp_packet_t *this) +{ + return this->packet->get_destination(this->packet); +} + +METHOD(packet_t, get_data, chunk_t, + private_esp_packet_t *this) +{ + return this->packet->get_data(this->packet); +} + +METHOD(packet_t, set_data, void, + private_esp_packet_t *this, chunk_t data) +{ + return this->packet->set_data(this->packet, data); +} + +METHOD(packet_t, skip_bytes, void, + private_esp_packet_t *this, size_t bytes) +{ + return this->packet->skip_bytes(this->packet, bytes); +} + +METHOD(packet_t, clone, packet_t*, + private_esp_packet_t *this) +{ + private_esp_packet_t *pkt; + + pkt = esp_packet_create_empty(this->packet->clone(this->packet)); + pkt->payload = chunk_clone(this->payload); + pkt->next_header = this->next_header; + return &pkt->public.packet; +} + METHOD(esp_packet_t, parse_header, bool, private_esp_packet_t *this, u_int32_t *spi) { bio_reader_t *reader; u_int32_t seq; - reader = bio_reader_create(this->packet_data); + reader = bio_reader_create(this->packet->get_data(this->packet)); if (!reader->read_uint32(reader, spi) || !reader->read_uint32(reader, &seq)) { @@ -142,16 +191,17 @@ METHOD(esp_packet_t, decrypt, status_t, { bio_reader_t *reader; u_int32_t spi, seq; - chunk_t spi_seq, iv, icv, ciphertext; + chunk_t data, iv, icv, ciphertext; crypter_t *crypter; signer_t *signer; chunk_free(&this->payload); + data = this->packet->get_data(this->packet); crypter = esp_context->get_crypter(esp_context); signer = esp_context->get_signer(esp_context); - reader = bio_reader_create(this->packet_data); + reader = bio_reader_create(data); if (!reader->read_uint32(reader, &spi) || !reader->read_uint32(reader, &seq) || !reader->read_data(reader, crypter->get_iv_size(crypter), &iv) || @@ -168,14 +218,13 @@ METHOD(esp_packet_t, decrypt, status_t, { DBG1(DBG_ESP, "ESP sequence number verification failed:\n " "src %H, dst %H, SPI %.8x [seq %u]", - this->src, this->dst, spi, seq); + get_source(this), get_destination(this), spi, seq); return VERIFY_ERROR; } DBG3(DBG_ESP, "ESP decryption:\n SPI %.8x [seq %u]\n IV %B\n " "encrypted %B\n ICV %B", spi, seq, &iv, &ciphertext, &icv); - spi_seq = chunk_create(this->packet_data.ptr, 8); - if (!signer->get_signature(signer, spi_seq, NULL) || + if (!signer->get_signature(signer, chunk_create(data.ptr, 8), NULL) || !signer->get_signature(signer, iv, NULL) || !signer->verify_signature(signer, ciphertext, icv)) { @@ -222,7 +271,7 @@ METHOD(esp_packet_t, encrypt, status_t, signer_t *signer; rng_t *rng; - chunk_free(&this->packet_data); + this->packet->set_data(this->packet, chunk_empty); if (!esp_context->next_seqno(esp_context, &next_seqno)) { @@ -303,7 +352,7 @@ METHOD(esp_packet_t, encrypt, status_t, "encrypted %B\n ICV %B", ntohl(spi), next_seqno, &iv, &ciphertext, &icv); - this->packet_data = writer->extract_buf(writer); + this->packet->set_data(this->packet, writer->extract_buf(writer)); writer->destroy(writer); return SUCCESS; } @@ -320,43 +369,33 @@ METHOD(esp_packet_t, get_payload, chunk_t, return this->payload; } -METHOD(esp_packet_t, get_packet_data, chunk_t, - private_esp_packet_t *this) -{ - return this->packet_data; -} - -METHOD(esp_packet_t, get_source, host_t*, - private_esp_packet_t *this) -{ - return this->src; -} - -METHOD(esp_packet_t, get_destination, host_t*, - private_esp_packet_t *this) -{ - return this->dst; -} - -METHOD(esp_packet_t, destroy, void, +METHOD2(esp_packet_t, packet_t, destroy, void, private_esp_packet_t *this) { chunk_free(&this->payload); - chunk_free(&this->packet_data); - this->src->destroy(this->src); - this->dst->destroy(this->dst); + this->packet->destroy(this->packet); free(this); } -static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst) +static private_esp_packet_t *esp_packet_create_empty(packet_t *packet) { private_esp_packet_t *this; INIT(this, .public = { + .packet = { + .set_source = _set_source, + .get_source = _get_source, + .set_destination = _set_destination, + .get_destination = _get_destination, + .get_data = _get_data, + .set_data = _set_data, + .skip_bytes = _skip_bytes, + .clone = _clone, + .destroy = _destroy, + }, .get_source = _get_source, .get_destination = _get_destination, - .get_packet_data = _get_packet_data, .get_payload = _get_payload, .get_next_header = _get_next_header, .parse_header = _parse_header, @@ -364,8 +403,7 @@ static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst) .encrypt = _encrypt, .destroy = _destroy, }, - .src = src, - .dst = dst, + .packet = packet, .next_header = IPPROTO_NONE, ); return this; @@ -374,13 +412,11 @@ static private_esp_packet_t *esp_packet_create_empty(host_t *src, host_t *dst) /** * Described in header. */ -esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst, - chunk_t packet_data) +esp_packet_t *esp_packet_create_from_packet(packet_t *packet) { private_esp_packet_t *this; - this = esp_packet_create_empty(src, dst); - this->packet_data = packet_data; + this = esp_packet_create_empty(packet); return &this->public; } @@ -389,14 +425,16 @@ esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst, * Described in header. */ esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst, - chunk_t payload, u_int8_t next_header) + chunk_t payload, + u_int8_t next_header) { private_esp_packet_t *this; + packet_t *packet; - this = esp_packet_create_empty(src, dst); + packet = packet_create_from_data(src, dst, chunk_empty); + this = esp_packet_create_empty(packet); this->next_header = next_header; this->payload = payload; return &this->public; } - diff --git a/src/libipsec/esp_packet.h b/src/libipsec/esp_packet.h index 473eeb4e5..7dbbd1986 100644 --- a/src/libipsec/esp_packet.h +++ b/src/libipsec/esp_packet.h @@ -27,6 +27,7 @@ #include <library.h> #include <utils/host.h> +#include <utils/packet.h> typedef struct esp_packet_t esp_packet_t; @@ -36,6 +37,11 @@ typedef struct esp_packet_t esp_packet_t; struct esp_packet_t { /** + * Implements packet_t interface to access the raw ESP packet + */ + packet_t packet; + + /** * Get the source address of this packet * * @return source host @@ -107,14 +113,6 @@ struct esp_packet_t { chunk_t (*get_payload)(esp_packet_t *this); /** - * Get the packet data to send / as received on the wire. - * - * @return encrypted packet data (internal data), - * chunk_empty if not encrypted - */ - chunk_t (*get_packet_data)(esp_packet_t *this); - - /** * Destroy an esp_packet_t */ void (*destroy)(esp_packet_t *this); @@ -124,13 +122,10 @@ struct esp_packet_t { /** * Create an ESP packet out of data from the wire. * - * @param src source address from which the packet was sent, owned - * @param dst destination address to which the packet was sent, owned - * @param data the packet data as received, gets owned + * @param packet the packet data as received, gets owned * @return esp_packet_t instance */ -esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst, - chunk_t data); +esp_packet_t *esp_packet_create_from_packet(packet_t *packet); /** * Create an ESP packet from a plaintext payload (e.g. inner IP packet) @@ -142,7 +137,8 @@ esp_packet_t *esp_packet_create_from_packet(host_t *src, host_t *dst, * @return esp_packet_t instance */ esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst, - chunk_t payload, u_int8_t next_header); + chunk_t payload, + u_int8_t next_header); #endif /** ESP_PACKET_H_ @}*/ |