Skip to content

Commit 5bafe1c

Browse files
committed
Fix zero-byte datagram handling and kqueue SO_NOSIGPIPE guard
- Preserve source endpoint for zero-byte datagrams on both reactor inline path (n >= 0) and IOCP completion handler - Allow zero-length UDP sends instead of short-circuiting them - Guard SO_NOSIGPIPE with #ifdef on kqueue UDP service
1 parent d43ed48 commit 5bafe1c

File tree

3 files changed

+7
-47
lines changed

3 files changed

+7
-47
lines changed

include/boost/corosio/native/detail/iocp/win_udp_service.hpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ recv_from_op::do_complete(
194194
// Extract source endpoint on success
195195
bool success =
196196
(op->dwError == 0 && !op->cancelled.load(std::memory_order_acquire));
197-
if (success && op->source_out && op->bytes_transferred > 0)
197+
if (success && op->source_out)
198198
{
199199
*op->source_out = from_sockaddr(op->source_storage);
200200
}
@@ -382,13 +382,6 @@ win_udp_socket_internal::send_to(
382382
op.wsabuf_count =
383383
static_cast<DWORD>(param.copy_to(bufs, send_to_op::max_buffers));
384384

385-
// Handle empty buffer: complete immediately with 0 bytes
386-
if (op.wsabuf_count == 0 || (op.wsabuf_count == 1 && bufs[0].size() == 0))
387-
{
388-
svc_.on_completion(&op, 0, 0);
389-
return std::noop_coroutine();
390-
}
391-
392385
for (DWORD i = 0; i < op.wsabuf_count; ++i)
393386
{
394387
op.wsabufs[i].buf = static_cast<char*>(bufs[i].data());
@@ -553,12 +546,6 @@ win_udp_socket_internal::send(
553546
op.wsabuf_count =
554547
static_cast<DWORD>(param.copy_to(bufs, udp_send_op::max_buffers));
555548

556-
if (op.wsabuf_count == 0 || (op.wsabuf_count == 1 && bufs[0].size() == 0))
557-
{
558-
svc_.on_completion(&op, 0, 0);
559-
return std::noop_coroutine();
560-
}
561-
562549
for (DWORD i = 0; i < op.wsabuf_count; ++i)
563550
{
564551
op.wsabufs[i].buf = static_cast<char*>(bufs[i].data());

include/boost/corosio/native/detail/kqueue/kqueue_udp_service.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,13 @@ kqueue_udp_service::open_datagram_socket(
264264
return make_err(errn);
265265
}
266266

267-
// SO_NOSIGPIPE for macOS/BSD
268-
int one = 1;
269-
if (::setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one)) != 0)
267+
// SO_NOSIGPIPE on macOS (where MSG_NOSIGNAL doesn't exist)
268+
#ifdef SO_NOSIGPIPE
270269
{
271-
int errn = errno;
272-
::close(fd);
273-
return make_err(errn);
270+
int one = 1;
271+
::setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one));
274272
}
273+
#endif
275274

276275
kq_impl->fd_ = fd;
277276

include/boost/corosio/native/detail/reactor/reactor_datagram_socket.hpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,6 @@ reactor_datagram_socket<
272272
op.iovec_count =
273273
static_cast<int>(param.copy_to(bufs, SendToOp::max_buffers));
274274

275-
if (op.iovec_count == 0 || (op.iovec_count == 1 && bufs[0].size() == 0))
276-
{
277-
op.h = h;
278-
op.ex = ex;
279-
op.ec_out = ec;
280-
op.bytes_out = bytes_out;
281-
op.start(token, static_cast<Derived*>(this));
282-
op.impl_ptr = this->shared_from_this();
283-
op.complete(0, 0);
284-
this->svc_.post(&op);
285-
return std::noop_coroutine();
286-
}
287-
288275
for (int i = 0; i < op.iovec_count; ++i)
289276
{
290277
op.iovecs[i].iov_base = bufs[i].data();
@@ -433,7 +420,7 @@ reactor_datagram_socket<
433420
{
434421
*ec = err ? make_err(err) : std::error_code{};
435422
*bytes_out = bytes;
436-
if (source && !err && n > 0)
423+
if (source && !err && n >= 0)
437424
*source = from_sockaddr(op.source_storage);
438425
return dispatch_coro(ex, h);
439426
}
@@ -580,19 +567,6 @@ reactor_datagram_socket<
580567
capy::mutable_buffer bufs[SendOp::max_buffers];
581568
op.iovec_count = static_cast<int>(param.copy_to(bufs, SendOp::max_buffers));
582569

583-
if (op.iovec_count == 0 || (op.iovec_count == 1 && bufs[0].size() == 0))
584-
{
585-
op.h = h;
586-
op.ex = ex;
587-
op.ec_out = ec;
588-
op.bytes_out = bytes_out;
589-
op.start(token, static_cast<Derived*>(this));
590-
op.impl_ptr = this->shared_from_this();
591-
op.complete(0, 0);
592-
this->svc_.post(&op);
593-
return std::noop_coroutine();
594-
}
595-
596570
for (int i = 0; i < op.iovec_count; ++i)
597571
{
598572
op.iovecs[i].iov_base = bufs[i].data();

0 commit comments

Comments
 (0)