added 2 more parameters to sys::write()
adding a tcp proxy script
This commit is contained in:
parent
c5799690b8
commit
b917920aa5
@ -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
267
hawk/scripts/tcp-proxy.awk
Normal 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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user