Receive packets directly into a buffer that can be retained in the send queue, rather than a buffer contained in the instance (whence they must be copied).
Signed-off-by: Zane Bitter <zane.bit...@gmail.com> --- exec/totemudp.c | 145 +++++++++++++++++++++++++++---------------------------- 1 files changed, 71 insertions(+), 74 deletions(-) diff --git a/exec/totemudp.c b/exec/totemudp.c index 42739d6..70cd5b6 100644 --- a/exec/totemudp.c +++ b/exec/totemudp.c @@ -170,12 +170,8 @@ struct totemudp_instance { void *udp_context; - char iov_buffer[FRAME_SIZE_MAX]; - char iov_buffer_flush[FRAME_SIZE_MAX]; - struct iovec totemudp_iov_recv; - struct iovec totemudp_iov_recv_flush; struct totemudp_socket totemudp_sockets; @@ -232,9 +228,6 @@ static void totemudp_instance_initialize (struct totemudp_instance *instance) instance->netif_state_report = NETIF_STATE_REPORT_UP | NETIF_STATE_REPORT_DOWN; - instance->totemudp_iov_recv.iov_base = instance->iov_buffer; - - instance->totemudp_iov_recv.iov_len = FRAME_SIZE_MAX; //sizeof (instance->iov_buffer); instance->totemudp_iov_recv_flush.iov_base = instance->iov_buffer_flush; instance->totemudp_iov_recv_flush.iov_len = FRAME_SIZE_MAX; //sizeof (instance->iov_buffer); @@ -258,11 +251,11 @@ do { \ static int authenticate_and_decrypt_sober ( struct totemudp_instance *instance, + struct security_header *header, struct iovec *iov, unsigned int iov_len) { unsigned char keys[48]; - struct security_header *header = (struct security_header *)iov[0].iov_base; prng_state keygen_prng_state; prng_state stream_prng_state; unsigned char *hmac_key = &keys[32]; @@ -271,6 +264,8 @@ static int authenticate_and_decrypt_sober ( unsigned char digest_comparison[HMAC_HASH_SIZE]; unsigned long len; + assert (iov_len == 1); + /* * Generate MAC, CIPHER, IV keys from private key */ @@ -295,8 +290,9 @@ static int authenticate_and_decrypt_sober ( hmac_init (&instance->totemudp_hmac_state, DIGEST_SHA1, hmac_key, 16); hmac_process (&instance->totemudp_hmac_state, - (unsigned char *)iov->iov_base + HMAC_HASH_SIZE, - iov->iov_len - HMAC_HASH_SIZE); + (unsigned char *)header + HMAC_HASH_SIZE, + sizeof (*header) - HMAC_HASH_SIZE); + hmac_process (&instance->totemudp_hmac_state, iov->iov_base, iov->iov_len); len = hash_descriptor[DIGEST_SHA1]->hashsize; assert (HMAC_HASH_SIZE >= len); @@ -309,10 +305,7 @@ static int authenticate_and_decrypt_sober ( /* * Decrypt the contents of the message with the cipher key */ - sober128_read ((unsigned char*)iov->iov_base + - sizeof (struct security_header), - iov->iov_len - sizeof (struct security_header), - &stream_prng_state); + sober128_read (iov->iov_base, iov->iov_len, &stream_prng_state); return (0); } @@ -574,21 +567,19 @@ out: static int authenticate_and_decrypt_nss ( struct totemudp_instance *instance, + struct security_header *header, struct iovec *iov, unsigned int iov_len) { PK11Context* enc_context = NULL; - SECStatus rv1, rv2; + SECStatus rv; int tmp1_outlen; unsigned int tmp2_outlen; unsigned char outbuf[FRAME_SIZE_MAX]; unsigned char digest[HMAC_HASH_SIZE]; - unsigned char *outdata; int result_len; - unsigned char *data; unsigned char *inbuf; size_t datalen; - struct security_header *header = (struct security_header *)iov[0].iov_base; SECItem no_params; SECItem ivdata; @@ -608,10 +599,6 @@ static int authenticate_and_decrypt_nss ( inbuf = (unsigned char *)iov[0].iov_base; datalen = iov[0].iov_len; } - data = inbuf + sizeof (struct security_header) - 16; - datalen = datalen - sizeof (struct security_header) + 16; - - outdata = outbuf + sizeof (struct security_header); /* Check the digest */ enc_context = PK11_CreateContextBySymKey ( @@ -628,14 +615,18 @@ static int authenticate_and_decrypt_nss ( return -1; } - PK11_DigestBegin(enc_context); + rv = PK11_DigestBegin(enc_context); + + rv |= PK11_DigestOp(enc_context, + (unsigned char *)header + HMAC_HASH_SIZE, + sizeof (*header) - HMAC_HASH_SIZE); + rv |= PK11_DigestOp(enc_context, inbuf, datalen); - rv1 = PK11_DigestOp(enc_context, data, datalen); - rv2 = PK11_DigestFinal(enc_context, digest, &tmp2_outlen, sizeof(digest)); + rv |= PK11_DigestFinal(enc_context, digest, &tmp2_outlen, sizeof(digest)); PK11_DestroyContext(enc_context, PR_TRUE); - if (rv1 != SECSuccess || rv2 != SECSuccess) { + if (rv != SECSuccess) { log_printf(instance->totemudp_log_level_security, "Digest check failed\n"); return -1; } @@ -645,12 +636,6 @@ static int authenticate_and_decrypt_nss ( return -1; } - /* - * Get rid of salt - */ - data += 16; - datalen -= 16; - /* Create cipher context for decryption */ ivdata.type = siBuffer; ivdata.data = header->salt; @@ -667,26 +652,27 @@ static int authenticate_and_decrypt_nss ( return -1; } - rv1 = PK11_CipherOp(enc_context, outdata, &tmp1_outlen, - sizeof(outbuf) - sizeof (struct security_header), - data, datalen); - if (rv1 != SECSuccess) { + rv = PK11_CipherOp(enc_context, outbuf, &tmp1_outlen, + sizeof(outbuf), inbuf, datalen); + if (rv != SECSuccess) { log_printf(instance->totemudp_log_level_security, "PK11_CipherOp (decrypt) failed (err %d)\n", PR_GetError()); } - rv2 = PK11_DigestFinal(enc_context, outdata + tmp1_outlen, &tmp2_outlen, - sizeof(outbuf) - tmp1_outlen); + rv |= PK11_DigestFinal(enc_context, outbuf + tmp1_outlen, &tmp2_outlen, + sizeof(outbuf) - tmp1_outlen); PK11_DestroyContext(enc_context, PR_TRUE); - result_len = tmp1_outlen + tmp2_outlen + sizeof (struct security_header); + result_len = tmp1_outlen + tmp2_outlen; /* Copy it back to the buffer */ copy_to_iovec(iov, iov_len, outbuf, result_len); - if (iov_len > 1) + if (iov_len > 1) { free(inbuf); + } - if (rv1 != SECSuccess || rv2 != SECSuccess) + if (rv != SECSuccess) { return -1; + } return 0; } @@ -795,6 +781,7 @@ static int encrypt_and_sign_worker ( static int authenticate_and_decrypt ( struct totemudp_instance *instance, + struct security_header *security_header, struct iovec *iov, unsigned int iov_len) { @@ -809,7 +796,7 @@ static int authenticate_and_decrypt ( iov[iov_len-1].iov_len -= 1; if (type == TOTEM_CRYPTO_SOBER) - res = authenticate_and_decrypt_sober(instance, iov, iov_len); + res = authenticate_and_decrypt_sober(instance, security_header, iov, iov_len); /* * Only try higher crypto options if NEW has been requested @@ -817,7 +804,7 @@ static int authenticate_and_decrypt ( if (instance->totem_config->crypto_accept == TOTEM_CRYPTO_ACCEPT_NEW) { #ifdef HAVE_LIBNSS if (type == TOTEM_CRYPTO_NSS) - res = authenticate_and_decrypt_nss(instance, iov, iov_len); + res = authenticate_and_decrypt_nss(instance, security_header, iov, iov_len); #endif } @@ -827,7 +814,7 @@ static int authenticate_and_decrypt ( */ if (res == -1) { iov[iov_len-1].iov_len += 1; - res = authenticate_and_decrypt_sober(instance, iov, iov_len); + res = authenticate_and_decrypt_sober(instance, security_header, iov, iov_len); } return res; @@ -1173,14 +1160,26 @@ static int net_deliver_fn ( { struct totemudp_instance *instance = (struct totemudp_instance *)data; struct msghdr msg_recv; - struct iovec *iovec; + struct iovec iovec[2]; + struct iovec *buf_iov = iovec; + unsigned int iovlen = 1; struct sockaddr_storage system_from; int bytes_received; - int res = 0; - unsigned char *msg_offset; - unsigned int size_delv; + struct security_header security_header; + char *buffer; - iovec = &instance->totemudp_iov_recv; + if (instance->totem_config->secauth == 1) { + iovec->iov_base = &security_header; + iovec->iov_len = sizeof (security_header); + buf_iov++; + iovlen++; + } + buffer = totemudp_buffer_alloc(); + if (!buffer) { + return (-1); + } + buf_iov->iov_base = buffer; + buf_iov->iov_len = FRAME_SIZE_MAX; /* * Receive datagram @@ -1188,7 +1187,7 @@ static int net_deliver_fn ( msg_recv.msg_name = &system_from; msg_recv.msg_namelen = sizeof (struct sockaddr_storage); msg_recv.msg_iov = iovec; - msg_recv.msg_iovlen = 1; + msg_recv.msg_iovlen = iovlen; #if !defined(COROSYNC_SOLARIS) msg_recv.msg_control = 0; msg_recv.msg_controllen = 0; @@ -1205,33 +1204,33 @@ static int net_deliver_fn ( instance->stats_recv += bytes_received; } - if ((instance->totem_config->secauth == 1) && - (bytes_received < sizeof (struct security_header))) { + if (instance->totem_config->secauth == 1) { + int res = 0; - log_printf (instance->totemudp_log_level_security, "Received message is too short... ignoring %d.\n", bytes_received); - return (0); - } + if (bytes_received < sizeof (struct security_header)) { + + log_printf (instance->totemudp_log_level_security, + "Received message is too short... ignoring %d.\n", + bytes_received); + return (0); + } + + buf_iov->iov_len = bytes_received - sizeof (struct security_header); - iovec->iov_len = bytes_received; - if (instance->totem_config->secauth == 1) { /* * Authenticate and if authenticated, decrypt datagram */ - res = authenticate_and_decrypt (instance, iovec, 1); + res = authenticate_and_decrypt (instance, &security_header, buf_iov, 1); if (res == -1) { - log_printf (instance->totemudp_log_level_security, "Received message has invalid digest... ignoring.\n"); + log_printf (instance->totemudp_log_level_security, + "Received message has invalid digest... ignoring.\n"); log_printf (instance->totemudp_log_level_security, "Invalid packet data\n"); - iovec->iov_len = FRAME_SIZE_MAX; return 0; } - msg_offset = (unsigned char *)iovec->iov_base + - sizeof (struct security_header); - size_delv = bytes_received - sizeof (struct security_header); } else { - msg_offset = (void *)iovec->iov_base; - size_delv = bytes_received; + buf_iov->iov_len = bytes_received; } /* @@ -1239,10 +1238,13 @@ static int net_deliver_fn ( */ instance->totemudp_deliver_fn ( instance->context, - msg_offset, - size_delv); + buf_iov->iov_base, + buf_iov->iov_len); + + if (!totembuf_is_retained (buffer)) { + totemudp_buffer_release (buffer); + } - iovec->iov_len = FRAME_SIZE_MAX; return (0); } @@ -1788,7 +1790,6 @@ int totemudp_initialize ( */ instance->totem_interface = &totem_config->interfaces[interface_no]; totemip_copy (&instance->mcast_address, &instance->totem_interface->mcast_addr); - memset (instance->iov_buffer, 0, FRAME_SIZE_MAX); /* * If threaded send requested, initialize thread group data structure @@ -1838,11 +1839,7 @@ void *totemudp_buffer_alloc (void) void *totemudp_buffer_retain (void *ptr) { - void *new_buf = totemudp_buffer_alloc(); - if (new_buf) { - memcpy (new_buf, ptr, FRAME_SIZE_MAX); - } - return new_buf; + return totembuf_retain (ptr); } void totemudp_buffer_release (void *ptr) _______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais