Skip to content

Commit

Permalink
Workaround TCP_NODELAY error on winsock
Browse files Browse the repository at this point in the history
Apparently winsock does not like setsockopt()
concurrently to async connect().  So delay
NODELAY until after connected.
  • Loading branch information
mdavidsaver committed Mar 29, 2024
1 parent 3e93627 commit 4bd8847
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/clientconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@ void Connection::startConnecting()

if(bufferevent_socket_connect(bev.get(), const_cast<sockaddr*>(&peerAddr->sa), peerAddr.size()))
throw std::runtime_error("Unable to begin connecting");
{
auto fd(bufferevent_getfd(bev.get()));
int opt = 1;
if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt))<0) {
auto err(SOCKERRNO);
log_warn_printf(io, "Unable to TCP_NODELAY: %d on %d\n", err, fd);
}
}

connect(std::move(bev));

Expand Down Expand Up @@ -144,6 +136,16 @@ void Connection::bevEvent(short events)
if(bev && (events&BEV_EVENT_CONNECTED)) {
log_debug_printf(io, "Connected to %s\n", peerName.c_str());

{
// after async connect() to avoid winsock specific race.
auto fd(bufferevent_getfd(bev.get()));
int opt = 1;
if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt))<0) {
auto err(SOCKERRNO);
log_warn_printf(io, "Unable to TCP_NODELAY: %d on %d\n", err, fd);
}
}

if(bufferevent_enable(bev.get(), EV_READ|EV_WRITE))
throw std::logic_error("Unable to enable BEV");

Expand Down

0 comments on commit 4bd8847

Please sign in to comment.