diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/plugins/ha_sync/ha_sync_socket.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/src/charon/plugins/ha_sync/ha_sync_socket.c b/src/charon/plugins/ha_sync/ha_sync_socket.c index b6b61d12c..dfc1c06df 100644 --- a/src/charon/plugins/ha_sync/ha_sync_socket.c +++ b/src/charon/plugins/ha_sync/ha_sync_socket.c @@ -81,9 +81,7 @@ static job_requeue_t send_message(job_data_t *data) this = data->this; chunk = data->message->get_encoding(data->message); - if (sendto(this->fd, chunk.ptr, chunk.len, 0, - this->remote->get_sockaddr(this->remote), - *this->remote->get_sockaddr_len(this->remote)) < chunk.len) + if (send(this->fd, chunk.ptr, chunk.len, 0) < chunk.len) { DBG1(DBG_CFG, "pushing HA sync message failed: %s", strerror(errno)); } @@ -95,20 +93,32 @@ static job_requeue_t send_message(job_data_t *data) */ static void push(private_ha_sync_socket_t *this, ha_sync_message_t *message) { - callback_job_t *job; - job_data_t *data; - - data = malloc_thing(job_data_t); - data->message = message; - data->this = this; - - /* we send sync message asynchronously. This is required, as sendto() - * is a blocking call if it acquires a policy. Otherwise we could - * end up in a deadlock, as we own an IKE_SA. */ - job = callback_job_create((callback_job_cb_t)send_message, - data, (void*)job_data_destroy, NULL); - charon->processor->queue_job(charon->processor, (job_t*)job); - sched_yield(); + chunk_t chunk; + + /* Try to send synchronously, but non-blocking. */ + chunk = message->get_encoding(message); + if (send(this->fd, chunk.ptr, chunk.len, MSG_DONTWAIT) < chunk.len) + { + if (errno == EAGAIN) + { + callback_job_t *job; + job_data_t *data; + + /* Fallback to asynchronous transmission. This is required, as sendto() + * is a blocking call if it acquires a policy. We could end up in a + * deadlock, as we own an IKE_SA. */ + data = malloc_thing(job_data_t); + data->message = message; + data->this = this; + + job = callback_job_create((callback_job_cb_t)send_message, + data, (void*)job_data_destroy, NULL); + charon->processor->queue_job(charon->processor, (job_t*)job); + return; + } + DBG1(DBG_CFG, "pushing HA sync message failed: %s", strerror(errno)); + } + message->destroy(message); } /** |