added 2 more parameters to sys::write()

adding a tcp proxy script
This commit is contained in:
hyung-hwan 2020-02-26 08:38:23 +00:00
parent c5799690b8
commit b917920aa5
2 changed files with 280 additions and 2 deletions

View File

@ -713,13 +713,24 @@ static int fnc_write (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{ {
hawk_bch_t* dptr; hawk_bch_t* dptr;
hawk_oow_t dlen; hawk_oow_t dlen;
hawk_ooi_t startpos = 0, maxlen = HAWK_TYPE_MAX(hawk_ooi_t);
hawk_val_t* a1; hawk_val_t* a1;
if (hawk_rtx_getnargs(rtx) >= 3 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &startpos) <= -1 || startpos < 0) startpos = 0;
else if (startpos > 1) startpos--; /* this position is 1-based */
if (hawk_rtx_getnargs(rtx) >= 4 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 3), &maxlen) <= -1) maxlen = HAWK_TYPE_MAX(hawk_ooi_t);
else if (maxlen < 0) maxlen = 0;
a1 = hawk_rtx_getarg(rtx, 1); a1 = hawk_rtx_getarg(rtx, 1);
dptr = hawk_rtx_getvalbcstr(rtx, a1, &dlen); dptr = hawk_rtx_getvalbcstr(rtx, a1, &dlen);
if (dptr) if (dptr)
{ {
rx = write(sys_node->ctx.u.file.fd, dptr, dlen); if (dlen > maxlen) dlen = maxlen;
if (startpos >= dlen) startpos = dlen;
dlen -= startpos;
rx = write(sys_node->ctx.u.file.fd, &dptr[startpos], dlen);
if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to write")); if (rx <= -1) rx = set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_T("unable to write"));
hawk_rtx_freevalbcstr (rtx, a1, dptr); hawk_rtx_freevalbcstr (rtx, a1, dptr);
} }
@ -4280,7 +4291,7 @@ static fnctab_t fnctab[] =
{ HAWK_T("unsetenv"), { { 1, 1, HAWK_NULL }, fnc_unsetenv, 0 } }, { HAWK_T("unsetenv"), { { 1, 1, HAWK_NULL }, fnc_unsetenv, 0 } },
{ HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } }, { HAWK_T("wait"), { { 1, 3, HAWK_T("vrv") }, fnc_wait, 0 } },
{ HAWK_T("waitonmux"), { { 2, 2, HAWK_T("vv") }, fnc_waitonmux, 0 } }, { HAWK_T("waitonmux"), { { 2, 2, HAWK_T("vv") }, fnc_waitonmux, 0 } },
{ HAWK_T("write"), { { 2, 2, HAWK_NULL }, fnc_write, 0 } }, { HAWK_T("write"), { { 2, 4, HAWK_NULL }, fnc_write, 0 } },
{ HAWK_T("writelog"), { { 2, 2, HAWK_NULL }, fnc_writelog, 0 } } { HAWK_T("writelog"), { { 2, 2, HAWK_NULL }, fnc_writelog, 0 } }
}; };

267
hawk/scripts/tcp-proxy.awk Normal file
View File

@ -0,0 +1,267 @@
@pragma entry main
@pragma implicit off
function break_bridge_by_local_fd (&localtab, &remotetab, fd, mx)
{
@local r;
r = localtab[fd];
sys::delfrommux (mx, fd);
sys::delfrommux (mx, r);
sys::close (fd);
sys::close (r);
delete localtab[fd];
delete localtab[fd,"pending"];
delete remotetab[r];
delete remotetab[r,"connecting"];
delete remotetab[r,"pending"];
}
function break_bridge_by_remote_fd (localtab, remotetab, fd, mx)
{
@local l;
l = remotetab[fd];
sys::delfrommux (mx, l);
sys::delfrommux (mx, fd);
sys::close (l);
sys::close (fd);
delete localtab[l];
delete localtab[l,"pending"];
delete remotetab[fd];
delete remotetab[fd,"connecting"];
delete remotetab[fd,"pending"];
}
function bridge_remote_to_local (localtab, remotetab, fd, mx)
{
@local len, buf;
len = sys::read(fd, buf, 8096);
if (len <= 0)
{
print "closing read error ", fd;
break_bridge_by_remote_fd (localtab, remotetab, fd, mx);
}
else
{
do
{
@local x;
x = sys::write(remotetab[fd], buf);
if (x == sys::RC_EAGAIN)
{
remotetab[fd,"pending"] = remotetab[fd,"pending"] %% buf;
break;
}
else if (x <= -1)
{
break_bridge_by_remote_fd (localtab, remotetab, fd, mx);
break;
}
len -= x;
if (len <= 0) break;
buf = substr(buf, x + 1);
}
while (1);
}
}
function bridge_local_to_remote (localtab, remotetab, fd, mx)
{
@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;
x = sys::write(localtab[fd], buf);
if (x == sys::RC_EAGAIN)
{
localtab[fd,"pending"] = localtab[fd,"pending"] %% buf;
## TODO: MOD mux for writing..
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)
{
@local localtab, remotetab
while (1)
{
@local x, i;
if ((x = sys::waitonmux(mx, 3.10)) <= -1)
{
print "Error: problem while waiting on multiplexer -", sys::errmsg();
break;
}
if (x == 0) continue; ## timed out
for (i = 0; i < x; i++)
{
@local fd, evmask;
if (sys::getmuxevt(mx, i, fd, evmask) <= -1) continue;
if (fd == ss)
{
## server socket event
@local l, r;
l = sys::accept(ss, sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK);
if (l <= -1)
{
print "Error: failed to accept connection -", sys::errmsg();
}
else
{
r = sys::socket(sys::AF_INET6, sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
if (r <= -1)
{
print "Error: unable to create remote socket for local socket", l, "-", sys::errmsg();
sys::close(l);
}
else
{
@local x;
x = sys::connect(r, remoteaddr);
if ((x <= -1 && x != sys::RC_EINPROG) || sys::addtomux(mx, r, sys::MUX_EVT_OUT) <= -1)
{
print "Unable to conneect to remote...", sys::errmsg();
sys::close (r);
sys::close (l);
}
else
{
localtab[l] = r;
remotetab[r] = l;
remotetab[r,"connecting"] = 1;
printf ("NEW SESSION %d %d\n", l, r);
}
}
}
}
else
{
## event on a client socket
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);
}
}
}
}
}
return 0;
}
function main (localaddr, remoteaddr, c)
{
@local ss, mx;
if (ARGC != 3)
{
printf ("Usage: %s local-address remote-address\n", ARGV[0]); ## TODO: add SCRIPTNAME to hawk interpreter
return -1;
}
mx = sys::openmux();
if (mx <= -1)
{
print "Error: unable to create multiplexer -", sys::errmsg();
return -1;
}
ss = sys::socket(sys::AF_INET6, sys::SOCK_STREAM | sys::SOCK_CLOEXEC | sys::SOCK_NONBLOCK, 0);
if (ss <= -1)
{
print "Error: unable to create socket -", sys::errmsg();
return -1;
}
sys::setsockopt(ss, sys::SOL_SOCKET, sys::SO_REUSEADDR, 1);
sys::setsockopt(ss, sys::SOL_SOCKET, sys::SO_REUSEPORT, 1);
if (sys::bind(ss, localaddr) <= -1 || sys::listen(ss, 0) <= -1)
{
print "Error: socket error -", sys::errmsg();
sys::close (ss);
return -1;
}
if (sys::addtomux(mx, ss, sys::MUX_EVT_IN) <= -1)
{
print "Error: unable to add server socket to multiplexer -", sys::errmsg();
sys::close (ss);
return -1;
}
serve_connections (mx, ss, remoteaddr);
sys::delfrommux (mx, ss);
sys::close (ss);
sys::close (mx);
}