You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
coroutine void do_proxy_half_duplex(int a, int b, chan ch)
{
int err = 0;
while (1) {
char buf[BUF_SIZE];
int more = 0;
size_t nbytes = tcprecvpkt(a, buf, sizeof(buf), -1, &more);
if (errno != 0) {
err = errno;
goto out;
}
size_t p = 0;
while (p < nbytes) {
size_t r = tcpsendpkt(b, &buf[p], nbytes - p, -1, more);
if (errno != 0) {
err = errno;
goto out;
}
p += r;
}
}
out:
if (err == ECONNRESET) {
shutdown(a, SHUT_RDWR);
shutdown(b, SHUT_RDWR);
} else {
shutdown(a, SHUT_RD);
shutdown(b, SHUT_WR);
}
chs(ch, int, err);
}
It really can't be much simpler. One coroutine reads from the client and writes to the server. Another reads from the server and writes to the client. Tadam.
But there is an issue. Imagine a case that server does not do read() and client does fill the buffers with write().
In such case we have:
first coroutine is stuck on write(to_the_server)
second coroutine is stuck on read(from_the_server)
The problem? Client connection my ECONNRESET and go away and we won't notice!
Solution: I think the right solution is to start another coroutine that would wait on fdwait(FDW_ERR) and force shutdown() on both connections in case any ECONNRESETS.
Sadly, libmill doesn't allow me to run coroutine and hang on fdwait(FDW_ERR) only in current implementation.
The text was updated successfully, but these errors were encountered:
I'm writing a simple TCP proxy. It's a pleasure to do that with libmill. But there is a corner case.
The design of proxy is rather straightforward. For every proxied connection I run something like this:
Where the do_proxy_half_duplex is:
It really can't be much simpler. One coroutine reads from the client and writes to the server. Another reads from the server and writes to the client. Tadam.
But there is an issue. Imagine a case that server does not do read() and client does fill the buffers with write().
In such case we have:
The problem? Client connection my ECONNRESET and go away and we won't notice!
Solution: I think the right solution is to start another coroutine that would wait on
fdwait(FDW_ERR)
and forceshutdown()
on both connections in case any ECONNRESETS.Sadly, libmill doesn't allow me to run coroutine and hang on
fdwait(FDW_ERR)
only in current implementation.The text was updated successfully, but these errors were encountered: