diff options
-rw-r--r-- | src/protocols/reqrep/req.c | 2 | ||||
-rw-r--r-- | src/protocols/survey/surveyor.c | 2 | ||||
-rw-r--r-- | src/transports/ws/sws.c | 20 | ||||
-rw-r--r-- | src/utils/msg.c | 26 | ||||
-rw-r--r-- | src/utils/msg.h | 2 |
5 files changed, 43 insertions, 9 deletions
diff --git a/src/protocols/reqrep/req.c b/src/protocols/reqrep/req.c index 27be656..fbe1f45 100644 --- a/src/protocols/reqrep/req.c +++ b/src/protocols/reqrep/req.c @@ -625,7 +625,7 @@ void nn_req_action_send (struct nn_req *self, int allow_delay) struct nn_pipe *to; /* Send the request. */ - nn_msg_cp (&msg, &self->task.request); + nn_msg_cp (&msg, &self->task.request, 0); rc = nn_xreq_send_to (&self->xreq.sockbase, &msg, &to); /* If the request cannot be sent at the moment wait till diff --git a/src/protocols/survey/surveyor.c b/src/protocols/survey/surveyor.c index ed03303..b96d1e1 100644 --- a/src/protocols/survey/surveyor.c +++ b/src/protocols/survey/surveyor.c @@ -482,7 +482,7 @@ static void nn_surveyor_resend (struct nn_surveyor *self) int rc; struct nn_msg msg; - nn_msg_cp (&msg, &self->tosend); + nn_msg_cp (&msg, &self->tosend, 0); rc = nn_xsurveyor_send (&self->xsurveyor.sockbase, &msg); errnum_assert (rc == 0, -rc); } diff --git a/src/transports/ws/sws.c b/src/transports/ws/sws.c index a6c101c..c82f919 100644 --- a/src/transports/ws/sws.c +++ b/src/transports/ws/sws.c @@ -165,9 +165,25 @@ static int nn_sws_send (struct nn_pipebase *self, struct nn_msg *msg) nn_assert_state (sws, NN_SWS_STATE_ACTIVE); nn_assert (sws->outstate == NN_SWS_OUTSTATE_IDLE); - /* Move the message to the local storage. */ nn_msg_term (&sws->outmsg); - nn_msg_mv (&sws->outmsg, msg); + + /* Move the message to the local storage. */ + if (sws->mode == NN_SWS_MODE_SERVER) { + + nn_msg_mv (&sws->outmsg, msg); + } + else { + + /* On the client we have to do hard copy of the message as we are + going to mask it. Masking the data in-place would cause other + co-owners of the message to access garbled data. */ + /* TODO: Can be optimised for exclusively owned messages. + Also we may want to mask the message in manageable chunks + (such as 4kB) so that there's no need to allocate 2x amount + of memory. */ + nn_msg_cp (&sws->outmsg, msg, 1); + nn_msg_term (msg); + } /* Serialise the message header. */ sws->outhdr [0] = NN_SWS_FIN | NN_SWS_OPCODE_BINARY; diff --git a/src/utils/msg.c b/src/utils/msg.c index 3c45b32..7efa774 100644 --- a/src/utils/msg.c +++ b/src/utils/msg.c @@ -52,11 +52,29 @@ void nn_msg_mv (struct nn_msg *dst, struct nn_msg *src) nn_chunkref_mv (&dst->body, &src->body); } -void nn_msg_cp (struct nn_msg *dst, struct nn_msg *src) +void nn_msg_cp (struct nn_msg *dst, struct nn_msg *src, int hard) { - nn_chunkref_cp (&dst->sphdr, &src->sphdr); - nn_chunkref_cp (&dst->hdrs, &src->hdrs); - nn_chunkref_cp (&dst->body, &src->body); + size_t sz; + + /* In the case of soft-copy only chunk references are increased. + No actual copying happens. */ + if (!hard) { + nn_chunkref_cp (&dst->sphdr, &src->sphdr); + nn_chunkref_cp (&dst->hdrs, &src->hdrs); + nn_chunkref_cp (&dst->body, &src->body); + return; + } + + /* Hard copy. Data are actually copied. */ + sz = nn_chunkref_size (&src->sphdr); + nn_chunkref_init (&dst->sphdr, sz); + memcpy (nn_chunkref_data (&dst->sphdr), nn_chunkref_data (&src->sphdr), sz); + sz = nn_chunkref_size (&src->hdrs); + nn_chunkref_init (&dst->hdrs, sz); + memcpy (nn_chunkref_data (&dst->hdrs), nn_chunkref_data (&src->hdrs), sz); + sz = nn_chunkref_size (&src->body); + nn_chunkref_init (&dst->body, sz); + memcpy (nn_chunkref_data (&dst->body), nn_chunkref_data (&src->body), sz); } void nn_msg_bulkcopy_start (struct nn_msg *self, uint32_t copies) diff --git a/src/utils/msg.h b/src/utils/msg.h index bf9a44d..8d4cc26 100644 --- a/src/utils/msg.h +++ b/src/utils/msg.h @@ -58,7 +58,7 @@ void nn_msg_mv (struct nn_msg *dst, struct nn_msg *src); /* Copies a message from src to dst. dst should not be initialised prior to the operation. */ -void nn_msg_cp (struct nn_msg *dst, struct nn_msg *src); +void nn_msg_cp (struct nn_msg *dst, struct nn_msg *src, int hard); /* Bulk copying is done by first invoking nn_msg_bulkcopy_start on the source message and specifying how many copies of the message will be made. Then, |