enhanced scripts/tcp-proxy.awk
This commit is contained in:
parent
8753eae27a
commit
aeff29f68e
@ -1,115 +1,215 @@
|
|||||||
@pragma entry main
|
@pragma entry main
|
||||||
@pragma implicit off
|
@pragma implicit off
|
||||||
|
|
||||||
function break_bridge_by_local_fd (&localtab, &remotetab, fd, mx)
|
function destroy_bridge (&brtab, fd, mx)
|
||||||
{
|
{
|
||||||
@local r;
|
@local pfd;
|
||||||
r = localtab[fd];
|
|
||||||
|
pfd = brtab[fd];
|
||||||
|
|
||||||
|
print "Info: Destroying", fd, pfd;
|
||||||
|
|
||||||
sys::delfrommux (mx, fd);
|
sys::delfrommux (mx, fd);
|
||||||
sys::delfrommux (mx, r);
|
sys::delfrommux (mx, pfd);
|
||||||
sys::close (fd);
|
sys::close (fd);
|
||||||
sys::close (r);
|
sys::close (pfd);
|
||||||
delete localtab[fd];
|
|
||||||
delete localtab[fd,"pending"];
|
delete brtab[fd];
|
||||||
delete remotetab[r];
|
delete brtab[fd,"connecting"];
|
||||||
delete remotetab[r,"connecting"];
|
delete brtab[fd,"pending"];
|
||||||
delete remotetab[r,"pending"];
|
delete brtab[fd,"evmask"];
|
||||||
|
delete brtab[fd,"eof"];
|
||||||
|
|
||||||
|
delete brtab[pfd];
|
||||||
|
delete brtab[pfd,"connecting"];
|
||||||
|
delete brtab[pfd,"pending"];
|
||||||
|
delete brtab[pfd,"evmask"];
|
||||||
|
delete brtab[pfd,"eof"];
|
||||||
}
|
}
|
||||||
|
|
||||||
function break_bridge_by_remote_fd (localtab, remotetab, fd, mx)
|
function prepare_bridge (&brtab, fd, pfd, mx)
|
||||||
{
|
{
|
||||||
@local l;
|
if (sys::addtomux(mx, pfd, sys::MUX_EVT_OUT) <= -1) return -1;
|
||||||
l = remotetab[fd];
|
|
||||||
sys::delfrommux (mx, l);
|
print "Info: Preparing", fd, pfd;
|
||||||
sys::delfrommux (mx, fd);
|
|
||||||
sys::close (l);
|
brtab[fd] = pfd;
|
||||||
sys::close (fd);
|
brtab[fd,"evmask"] = 0;
|
||||||
delete localtab[l];
|
|
||||||
delete localtab[l,"pending"];
|
brtab[pfd] = fd;
|
||||||
delete remotetab[fd];
|
brtab[pfd,"connecting"] = 1;
|
||||||
delete remotetab[fd,"connecting"];
|
brtab[pfd,"evmask"] = sys::MUX_EVT_OUT;
|
||||||
delete remotetab[fd,"pending"];
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bridge_remote_to_local (localtab, remotetab, fd, mx)
|
function establish_bridge (&brtab, fd, mx)
|
||||||
{
|
{
|
||||||
@local len, buf;
|
@local pfd;
|
||||||
|
|
||||||
|
pfd = brtab[fd];
|
||||||
|
if (sys::addtomux(mx, pfd, sys::MUX_EVT_IN) <= -1 ||
|
||||||
|
sys::modinmux(mx, fd, sys::MUX_EVT_IN) <= -1) return -1;
|
||||||
|
|
||||||
|
brtab[fd,"evmask"] = sys::MUX_EVT_IN;
|
||||||
|
brtab[pfd,"evmask"] = sys::MUX_EVT_IN;
|
||||||
|
|
||||||
|
delete brtab[fd,"connecting"];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_bridge_eof (&brtab, fd, mx)
|
||||||
|
{
|
||||||
|
@local pfd, evmask;
|
||||||
|
|
||||||
|
pfd = brtab[fd];
|
||||||
|
|
||||||
|
evmask = brtab[fd,"evmask"] & ~~sys::MUX_EVT_IN;
|
||||||
|
if (sys::modinmux(mx, fd, evmask) <= -1) return -1;
|
||||||
|
brtab[fd,"evmask"] = evmask;
|
||||||
|
brtab[fd,"eof"] = 1;
|
||||||
|
|
||||||
|
## EOF on fd, disable transmission on pfd if no pending
|
||||||
|
if (length(brtab[pfd,"pending"]) == 0) sys::shutdown (pfd, sys::SHUT_WR);
|
||||||
|
|
||||||
|
# if peer fd reached eof and there are no pending data, arrange to abort the bridge
|
||||||
|
if (brtab[pfd,"eof"] != 0 && length(brtab[pfd,"pending"]) == 0 && length(brtab[fd,"pending"]) == 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bridge_traffic (&brtab, fd, mx)
|
||||||
|
{
|
||||||
|
@local len, buf, pfd, pos, x, evmask;
|
||||||
|
|
||||||
|
pfd = brtab[fd];
|
||||||
|
|
||||||
len = sys::read(fd, buf, 8096);
|
len = sys::read(fd, buf, 8096);
|
||||||
if (len <= 0)
|
if (len <= -1)
|
||||||
{
|
{
|
||||||
print "closing read error ", fd;
|
return -1;
|
||||||
break_bridge_by_remote_fd (localtab, remotetab, fd, mx);
|
}
|
||||||
|
else if (len == 0)
|
||||||
|
{
|
||||||
|
return handle_bridge_eof (brtab, fd, mx);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 1;
|
||||||
|
while (pos <= len)
|
||||||
|
{
|
||||||
|
x = sys::write(pfd, buf, pos);
|
||||||
|
if (x == sys::RC_EAGAIN)
|
||||||
|
{
|
||||||
|
evmask = brtab[fd,"evmask"] & ~~sys::MUX_EVT_IN;
|
||||||
|
if (sys::modinmux(mx, fd, evmask) <= -1) return -1;
|
||||||
|
brtab[fd,"evmask"] = evmask;
|
||||||
|
|
||||||
|
evmask = brtab[pfd,"evmask"] | sys::MUX_EVT_OUT;
|
||||||
|
if (sys::modinmux(mx, pfd, evmask) <= -1) return -1;
|
||||||
|
brtab[pfd,"evmask"] = evmask;
|
||||||
|
|
||||||
|
brtab[pfd,"pending"] %%= substr(buf, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (x <= -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bridge_pendind_data (&brtab, fd, mx)
|
||||||
|
{
|
||||||
|
@local pending_data, pos, len, x, pfd, evmask;
|
||||||
|
|
||||||
|
pfd = brtab[fd];
|
||||||
|
pending_data = brtab[fd,"pending"];
|
||||||
|
|
||||||
|
len = length(pending_data);
|
||||||
|
pos = 1;
|
||||||
|
while (pos <= len)
|
||||||
|
{
|
||||||
|
x = sys::write(fd, pending_data, pos);
|
||||||
|
if (x == sys::RC_EAGAIN)
|
||||||
|
{
|
||||||
|
brtab[fd,"pending"] = substr(pending_data, pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pos += x;
|
||||||
|
}
|
||||||
|
|
||||||
|
## sent all pending data.
|
||||||
|
delete brtab[fd,"pending"];
|
||||||
|
|
||||||
|
evmask = brtab[fd,"evmask"] & ~~sys::MUX_EVT_OUT;
|
||||||
|
if (sys::modinmux(mx, fd, evmask) <= -1) return -1;
|
||||||
|
brtab[fd,"evmask"] = evmask;
|
||||||
|
|
||||||
|
if (brtab[pfd,"eof"] == 0)
|
||||||
|
{
|
||||||
|
evmask = brtab[pfd,"evmask"] | sys::MUX_EVT_IN;
|
||||||
|
if (sys::modinmux(mx, pfd, evmask) <= -1) return -1;
|
||||||
|
brtab[pfd,"evmask"] = evmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_bridge_event (&brtab, fd, mx, evmask)
|
||||||
|
{
|
||||||
|
if (evmask & sys::MUX_EVT_ERR)
|
||||||
|
{
|
||||||
|
destroy_bridge (brtab, fd, mx);
|
||||||
|
}
|
||||||
|
else if (evmask & sys::MUX_EVT_HUP)
|
||||||
|
{
|
||||||
|
print "Info: HUP detected on", fd;
|
||||||
|
if (handle_bridge_eof(brtab, fd, mx) <= -1)
|
||||||
|
{
|
||||||
|
destroy_bridge (brtab, fd, mx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do
|
if (evmask & sys::MUX_EVT_OUT)
|
||||||
{
|
{
|
||||||
@local x;
|
if ((fd,"connecting") in brtab)
|
||||||
|
|
||||||
x = sys::write(remotetab[fd], buf);
|
|
||||||
if (x == sys::RC_EAGAIN)
|
|
||||||
{
|
{
|
||||||
remotetab[fd,"pending"] = remotetab[fd,"pending"] %% buf;
|
## remote peer connection
|
||||||
break;
|
if (establish_bridge(brtab, fd, mx) <= -1)
|
||||||
|
{
|
||||||
|
destroy_bridge (brtab, fd, mx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (x <= -1)
|
else if ((fd,"pending") in brtab)
|
||||||
{
|
{
|
||||||
break_bridge_by_remote_fd (localtab, remotetab, fd, mx);
|
if (bridge_pending_data(brtab, fd, mx) <= -1)
|
||||||
break;
|
{
|
||||||
|
destroy_bridge (brtab, fd, mx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
len -= x;
|
|
||||||
if (len <= 0) break;
|
|
||||||
|
|
||||||
buf = substr(buf, x + 1);
|
|
||||||
}
|
}
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function bridge_local_to_remote (localtab, remotetab, fd, mx)
|
if (evmask & sys::MUX_EVT_IN)
|
||||||
{
|
|
||||||
@local len, buf;
|
|
||||||
|
|
||||||
len = sys::read(fd, buf, 8096);
|
|
||||||
if (len <= 0)
|
|
||||||
{
|
|
||||||
print "closing read error ", fd;
|
|
||||||
break_bridge_by_local_fd (localtab, remotetab, fd, mx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("ABOUT TO WRITE TO REMOTE........\n");
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
@local x;
|
if (bridge_traffic(brtab, fd, mx) <= -1)
|
||||||
|
|
||||||
x = sys::write(localtab[fd], buf);
|
|
||||||
if (x == sys::RC_EAGAIN)
|
|
||||||
{
|
{
|
||||||
localtab[fd,"pending"] = localtab[fd,"pending"] %% buf;
|
destroy_bridge (brtab, fd, mx);
|
||||||
## TODO: MOD mux for writing..
|
return;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if (x <= -1)
|
|
||||||
{
|
|
||||||
break_bridge_by_local_fd (localtab, remotetab, fd, mx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
len -= x;
|
|
||||||
if (len <= 0) break;
|
|
||||||
|
|
||||||
buf = substr(buf, x + 1);
|
|
||||||
}
|
}
|
||||||
while (1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function serve_connections (mx, ss, remoteaddr)
|
function serve_connections (mx, ss, remoteaddr)
|
||||||
{
|
{
|
||||||
@local localtab, remotetab
|
@local brtab, remotetab
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -142,7 +242,7 @@ function serve_connections (mx, ss, remoteaddr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r = sys::socket(sys::AF_INET6, sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
|
r = sys::socket(sys::sockaddrdom(remoteaddr), sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
|
||||||
if (r <= -1)
|
if (r <= -1)
|
||||||
{
|
{
|
||||||
print "Error: unable to create remote socket for local socket", l, "-", sys::errmsg();
|
print "Error: unable to create remote socket for local socket", l, "-", sys::errmsg();
|
||||||
@ -150,68 +250,22 @@ function serve_connections (mx, ss, remoteaddr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@local x;
|
@local rc;
|
||||||
x = sys::connect(r, remoteaddr);
|
rc = sys::connect(r, remoteaddr);
|
||||||
if ((x <= -1 && x != sys::RC_EINPROG) || sys::addtomux(mx, r, sys::MUX_EVT_OUT) <= -1)
|
if ((rc <= -1 && rc != sys::RC_EINPROG) || prepare_bridge(brtab, l, r, mx) <= -1)
|
||||||
{
|
{
|
||||||
print "Unable to conneect to remote...", sys::errmsg();
|
print "Error: unable to conneect to", remoteaddr, "-", sys::errmsg();
|
||||||
sys::close (r);
|
sys::close (r);
|
||||||
sys::close (l);
|
sys::close (l);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
localtab[l] = r;
|
|
||||||
remotetab[r] = l;
|
|
||||||
remotetab[r,"connecting"] = 1;
|
|
||||||
printf ("NEW SESSION %d %d\n", l, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
## event on a client socket
|
if (fd in brtab) handle_bridge_event (brtab, fd, mx, evmask);
|
||||||
if (fd in remotetab)
|
|
||||||
{
|
|
||||||
if (evmask & (sys::MUX_EVT_HUP | sys::MUX_EVT_ERR))
|
|
||||||
{
|
|
||||||
print "closing HUP ERR", fd;
|
|
||||||
break_bridge_by_remote_fd (localtab, remotetab, fd, mx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (evmask & sys::MUX_EVT_OUT)
|
|
||||||
{
|
|
||||||
if ((fd,"connecting") in remotetab)
|
|
||||||
{
|
|
||||||
## remote connected
|
|
||||||
sys::addtomux (mx, remotetab[fd], sys::MUX_EVT_IN);
|
|
||||||
sys::modinmux (mx, fd, sys::MUX_EVT_IN);
|
|
||||||
delete remotetab[fd,"connecting"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evmask & sys::MUX_EVT_IN)
|
|
||||||
{
|
|
||||||
bridge_remote_to_local (localtab, remotetab, fd, mx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd in localtab)
|
|
||||||
{
|
|
||||||
if (evmask & (sys::MUX_EVT_HUP | sys::MUX_EVT_ERR))
|
|
||||||
{
|
|
||||||
print "closing HUP ERR local", fd;
|
|
||||||
break_bridge_by_local_fd (localtab, remotetab, fd, mx);
|
|
||||||
}
|
|
||||||
else if (evmask & sys::MUX_EVT_IN)
|
|
||||||
{
|
|
||||||
print "event on " fd;
|
|
||||||
bridge_local_to_remote (localtab, remotetab, fd, mx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +289,7 @@ function main (localaddr, remoteaddr, c)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss = sys::socket(sys::AF_INET6, sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
|
ss = sys::socket(sys::sockaddrdom(localaddr), sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
|
||||||
if (ss <= -1)
|
if (ss <= -1)
|
||||||
{
|
{
|
||||||
print "Error: unable to create socket -", sys::errmsg();
|
print "Error: unable to create socket -", sys::errmsg();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user