• Proxy Service Issues

    From Drakmir@VERT/HDONE to All on Thursday, October 06, 2005 09:44:00
    I am trying to write a simple socket proxy in Synchronet's Javascript language, and having a very hard time of it. The code below is my latest attempt, but I've tried many variations on that theme (including blocking sockets, using send/receive buffers, etc).

    All of them either result in a crash in the services module or a lockup of all networking (including non synchronet) on the computer. I'm running with Synchronet 3.12 and on Win2k.

    Can someone assist with this and tell me what I'm doing wrong?

    Thanks!

    Code follows.

    Alan Wood

    ----- CODE ------

    load("sockdefs.js");

    function CopyData(socketA, socketB)
    {
    if (socketA.poll())
    {
    if (socketB.poll(0, true))
    {
    var nBytes = socketA.nread;
    var readVal = socketA.recvBin(1);

    if ((readVal > 0) && (socketA.error == 0))
    {
    if (!socketB.sendBin(readVal, 1))
    {
    throw ("Error writing to socket");
    }
    }
    }
    }
    }

    try
    {
    if (argc < 2)
    {
    throw("No parameters passed.");
    };

    var proxySocket = new Socket(SOCK_STREAM);
    proxySocket.nonblocking = 1;
    client.socket.nonblocking = 1;

    if (proxySocket.connect(argv[0], argv[1]))
    {
    while((client.socket.is_connected) && (proxySocket.is_connected) && (!proxySocket.error) && (!client.socket.error))
    {
    CopyData(client.socket, proxySocket);
    yield();

    CopyData(proxySocket, client.socket);
    yield();
    }

    proxySocket.close();
    }
    else
    {
    throw("Error connecting to proxied socket.");
    }
    }
    catch(E)
    {
    log("Caught error - " + E);
    exit(-1);
    }

    exit(0);

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Digital Man@VERT to Drakmir on Thursday, October 06, 2005 18:44:45
    Re: Proxy Service Issues
    By: Drakmir to All on Thu Oct 06 2005 09:44 am

    I am trying to write a simple socket proxy in Synchronet's Javascript langua and having a very hard time of it. The code below is my latest attempt, but I've tried many variations on that theme (including blocking sockets, using send/receive buffers, etc).

    All of them either result in a crash in the services module or a lockup of a networking (including non synchronet) on the computer. I'm running with Synchronet 3.12 and on Win2k.

    I tried your script (using the ;EXEC sysop command to just loop back to localhost, port 23) and it was able to receive okay, but slowing, it wasn't able to send. There was no crashing or lockups anything.

    I'll have to play with it later. Have you seen exec/socktest.js? It does very much what you're trying to, but faster (transmits and receives in blocks) and works for both transmit and receive. I think it's a pretty simple example.

    digital man

    Snapple "Real Fact" #11:
    Flamingos are pink because they eat shrimp.

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 07, 2005 00:25:00
    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works for my application. :)

    That proxy is slow because I removed block read/write since I wasn't sure what was going wrong. It was the simpliest example I could get to fail and not take down the computer with it.

    Thanks again!

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 07, 2005 00:38:00
    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:25 pm

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works for my application. :)

    That proxy is slow because I removed block read/write since I wasn't sure wh was going wrong. It was the simpliest example I could get to fail and not t down the computer with it.

    Thanks again!

    Alan
    So, I adapted socktest to read from client.socket instead of console, and for some reason it won't read the input. I basically just changed the RAW mode inkey for the same if logic above (client.socket.data_waiting).

    Is there a socket option that has to be set or something?

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 07, 2005 00:50:00
    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:38 pm

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:25 pm

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works for m application. :)

    That proxy is slow because I removed block read/write since I wasn't sure was going wrong. It was the simpliest example I could get to fail and no down the computer with it.

    Thanks again!

    Alan
    So, I adapted socktest to read from client.socket instead of console, and fo some reason it won't read the input. I basically just changed the RAW mode inkey for the same if logic above (client.socket.data_waiting).

    Is there a socket option that has to be set or something?

    Alan
    The following code has the issue above (no read of the client socket for some reason):

    while(socket.is_connected && client.socket.is_connected)
    {
    if(socket.data_waiting)
    {
    buf = socket.read();
    client.socket.write(buf);
    continue;
    }

    if(client.socket.data_waiting)
    {
    buf = client.socket.read();
    socket.write(buf);
    continue;
    }
    sleep(1);
    }

    Changing it to:

    while(socket.is_connected && client.socket.is_connected)
    {
    if(socket.data_waiting)
    {
    buf = socket.readBin(1);
    client.socket.writeBin(buf, 1);
    continue;
    }

    if(client.socket.data_waiting)
    {
    buf = client.socket.readBin(1);
    socket.writeBin(buf, 1);
    continue;
    }
    sleep(1);
    }

    Causes the crash condition. I know I switched to readBin/writeBin when I had problems with read/write interpreting something I didn't want it to interpret. Not sure of the specifics anymore, so I'll try with read/write again some more to see if I can figure out a combination that allows for both read and write.

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 07, 2005 01:25:00
    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:50 pm

    I think I have a solution, although the problem is interesting.

    I changed the read code to be the following:

    if(socket.data_waiting)
    {
    var numRead = socket.nread;
    buf = socket.read();
    if (numRead != buf.length)
    {
    log("2 - " + numRead + " vs. " + buf.length);
    }
    client.socket.write(buf);
    continue;
    }
    sleep(1);

    And noticed that the string being returned from "read" had the wrong number of bytes occasionally. I assume there are embedded \0 characters in the telnet responses?

    Anyway, switching to the following read code seems to help:

    if(client.socket.data_waiting)
    {
    var numRead = client.socket.nread;
    if (numRead >= 512) numRead = 512;

    while(numRead > 4)
    {
    buf = client.socket.recvBin(4);
    socket.sendBin(buf, 4);
    numRead -= 4;
    }

    if (numRead > 0)
    {
    buf = client.socket.recvBin(numRead);
    socket.sendBin(buf, numRead);
    }
    continue;
    }

    I'll see if that has any weird effects.

    I'm signing off now.

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Digital Man@VERT to Drakmir on Thursday, October 06, 2005 22:27:27
    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Fri Oct 07 2005 12:38 am

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:25 pm

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works for m application. :)

    That proxy is slow because I removed block read/write since I wasn't sure was going wrong. It was the simpliest example I could get to fail and no down the computer with it.

    Thanks again!

    So, I adapted socktest to read from client.socket instead of console, and fo some reason it won't read the input. I basically just changed the RAW mode inkey for the same if logic above (client.socket.data_waiting).

    Is there a socket option that has to be set or something?

    Yes, you can't perform I/O on the client's socket descriptor while the BBS's input thread is servicing the socking. You must set console.lock_input to true before accessing the client's socket directly and set it to to false when you're done.

    digital man

    Snapple "Real Fact" #12:
    Emus and Kangaroos cannot walk backwards.

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 07, 2005 09:46:00
    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 11:27 pm

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Fri Oct 07 2005 12:38 am

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:25 pm

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works fo application. :)

    That proxy is slow because I removed block read/write since I wasn't s was going wrong. It was the simpliest example I could get to fail and down the computer with it.

    Thanks again!

    So, I adapted socktest to read from client.socket instead of console, and some reason it won't read the input. I basically just changed the RAW mo inkey for the same if logic above (client.socket.data_waiting).

    Is there a socket option that has to be set or something?

    Yes, you can't perform I/O on the client's socket descriptor while the BBS's input thread is servicing the socking. You must set console.lock_input to tr before accessing the client's socket directly and set it to to false when you're done.

    digital man

    Snapple "Real Fact" #12:
    Emus and Kangaroos cannot walk backwards.

    The problem with that is when you have a "service", the console object doesn't exist.

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Drakmir@VERT/HDONE to All on Friday, October 07, 2005 09:56:00
    Re: Proxy Service Issues
    By: Drakmir to All on Thu Oct 06 2005 08:44 am

    So, after working on it last night and with some hints from Digital Man, I've come up with something that seems to work to proxy a socket. There is only one unknown, and I've noticed that the use of "sendBin" seems to be what is crashing my computer. (If I use any number of bytes other that 4 it seems to occasionaly crash).

    The one sticky point is that when using "peek" or "read", sometimes you get a string that is shorter than the number of bytes available to you. The only thing I can think of is that there is a embedded \0 character in the data stream which C is then reading as the end of the string. It would help to have a read/write that dealt with the "string" we provide as a buffer instead. I assume this is true because doing:

    socket.send("test\0test2"); only outputs "test".

    Alan

    -+- Code ---
    load("sockdefs.js");

    function sendData(socketA, socketB)
    {
    var bRetVal = false;
    var buf;

    if(socketA.data_waiting)
    {
    var numRead = socketA.nread;
    if (numRead > 512) numRead = 512;
    buf = socketA.peek(numRead);

    if (numRead != buf.length)
    {
    numRead = buf.length;
    buf = socketA.recv(numRead + 1); // Not sure what we are skipping here, but it seems harmless? Maybe a zero?
    socketB.send(buf);
    }
    else
    {
    buf = socketA.recv(numRead);
    socketB.send(buf);
    }

    bRetVal = true;
    }

    return bRetVal;
    }

    try
    {
    if (argc < 2)
    {
    throw("No parameters passed.");
    };

    var socket = new Socket();

    if(!socket.bind()) {
    throw("!bind error " + socket.last_error + "\r\n");
    exit();
    }

    var addr=argv[0];
    var port=argv[1];

    if(!socket.connect(addr,port)) {
    throw("!connect error " + socket.last_error + "\r\n");
    exit();
    }

    while(socket.is_connected && client.socket.is_connected)
    {
    if (sendData(socket, client.socket)) continue;
    if (sendData(client.socket, socket)) continue;
    sleep(1);
    }
    }
    catch(E)
    {
    log("Caught error - " + E);
    exit(-1);
    }

    exit(0);

    ---
    Synchronet Holodeck One - bbs.holodeckone.com
  • From Digital Man@VERT to Drakmir on Tuesday, October 11, 2005 16:51:14
    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Fri Oct 07 2005 09:46 am

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 11:27 pm

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Fri Oct 07 2005 12:38 am

    Re: Proxy Service Issues
    By: Drakmir to Digital Man on Thu Oct 06 2005 11:25 pm

    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Thu Oct 06 2005 07:44 pm

    I hadn't seen that one. I'll take a look at it and see if it works application. :)

    That proxy is slow because I removed block read/write since I wasn' was going wrong. It was the simpliest example I could get to fail down the computer with it.

    Thanks again!

    So, I adapted socktest to read from client.socket instead of console, some reason it won't read the input. I basically just changed the RAW inkey for the same if logic above (client.socket.data_waiting).

    Is there a socket option that has to be set or something?

    Yes, you can't perform I/O on the client's socket descriptor while the BB input thread is servicing the socking. You must set console.lock_input to before accessing the client's socket directly and set it to to false when you're done.

    The problem with that is when you have a "service", the console object doesn exist.

    When run as a service, there is not "input_thread" (the service is expected to interact with the socket directly), so the locking is not necessary.

    digital man

    Snapple "Real Fact" #90:
    The average raindrop falls at 7mph.

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net
  • From Digital Man@VERT to Drakmir on Tuesday, October 11, 2005 17:18:55
    Re: Proxy Service Issues
    By: Drakmir to All on Fri Oct 07 2005 09:56 am

    Re: Proxy Service Issues
    By: Drakmir to All on Thu Oct 06 2005 08:44 am

    So, after working on it last night and with some hints from Digital Man, I'v come up with something that seems to work to proxy a socket. There is only o unknown, and I've noticed that the use of "sendBin" seems to be what is crashing my computer. (If I use any number of bytes other that 4 it seems t occasionaly crash).

    What value (for number of byte) did you use when it crashed? Do you have example code that can reproduce this crash?

    The one sticky point is that when using "peek" or "read", sometimes you get string that is shorter than the number of bytes available to you. The only thing I can think of is that there is a embedded \0 character in the data stream which C is then reading as the end of the string. It would help to h a read/write that dealt with the "string" we provide as a buffer instead. I assume this is true because doing:

    socket.send("test\0test2"); only outputs "test".

    Ah, true. That'll be fixed for the next release. :-)

    digital man

    Snapple "Real Fact" #8:
    A bee has 5 eyes.

    ---
    Synchronet Vertrauen Home of Synchronet [vert/cvs/bbs].synchro.net
  • From Drakmir@VERT/HDONE to Digital Man on Friday, October 14, 2005 11:35:00
    Re: Proxy Service Issues
    By: Digital Man to Drakmir on Tue Oct 11 2005 06:18 pm

    Re: Proxy Service Issues
    By: Drakmir to All on Fri Oct 07 2005 09:56 am

    Re: Proxy Service Issues
    By: Drakmir to All on Thu Oct 06 2005 08:44 am

    So, after working on it last night and with some hints from Digital Man, come up with something that seems to work to proxy a socket. There is onl unknown, and I've noticed that the use of "sendBin" seems to be what is crashing my computer. (If I use any number of bytes other that 4 it seem occasionaly crash).

    What value (for number of byte) did you use when it crashed? Do you have example code that can reproduce this crash?

    The one sticky point is that when using "peek" or "read", sometimes you g string that is shorter than the number of bytes available to you. The on thing I can think of is that there is a embedded \0 character in the data stream which C is then reading as the end of the string. It would help t a read/write that dealt with the "string" we provide as a buffer instead. assume this is true because doing:

    socket.send("test\0test2"); only outputs "test".

    Ah, true. That'll be fixed for the next release. :-)

    digital man

    Snapple "Real Fact" #8:
    A bee has 5 eyes.

    Thanks! That should do it for me.

    I've changed the proxy code and TWGSRobotCode to send the byte, and over the past 3 days I've had no lockups. So, even though it was crashing using "sendBin(0, 1)" (since commenting out that code made the crash go away), I don't think it was that in particular. Maybe something that I was doing around it made that function fail dramatically?

    Anyway, the new proxy code sends the zero bytes now. I don't have an example to send you digital man, but if I get around to trying to recreate the crashes, I'll send it in. :)

    Thanks again for your help!

    Alan

    ---
    Synchronet Holodeck One - bbs.holodeckone.com