users@grizzly.java.net

Re: Tunnel implementation

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Mon, 04 Jun 2007 14:09:39 -0400

Hi,

Karsten Ohme wrote:
> On Mon, Jun 04, 2007 at 04:08:25PM +0200, Oleksiy Stashok wrote:
>> Hello Karsten,
>>
>> here I wrote simple tunnel implementation.
>> It is simplified, as write operations are done in blocking mode, but
>> hope it will help you.
>
> Thanks a lot. Well, I get AlreadyConnectedExceptions if I connect more
> than once, the aquired connector seems to be already in use. What
> was the reason I could not allocate a
> new ConnectorHandler with new TCPConnectorHandler()? Well, but this helps
> also only limited: Every second connection does not work.
>
> I have spend the day to get an own solution, but I failed. The first
> SelectionKey which is processed is always OP_READ, not an OP_ACCEPT. I
> noticed that the ProtocolFilter chain is only used if no CallbackHandler is
> attached (for which
> scenario is a CallbackHandler good for, and when a ProtocolFilter if they exclude
> each other?),

The idea here is for the client, to make it simple, to avoid having to
learn/build a ProtocolFilter by default but just register a
CallbackHandler. If you want to invoke the ProtocolChain/ProtocolFilter
from a CallBack, you can do it by invoking Context.execute().

Thanks

-- Jeanfrancois





so I attached null to the key after I got a connection. The sources are
> attached. I don't know why this programm fails.
>
> I also attached a modified version of the ConnectorHandler interface. A Channel
> can now be attached. For me it was useful or the only way I had seen to reuse a the
> convenient TCPConnectorHandler.
>
> Best Regards, Karsten
>
>> WBR,
>> Alexey.
>>
>> Karsten Ohme wrote:
>>> On Fri, Jun 01, 2007 at 05:26:18PM +0200, Oleksiy Stashok wrote:
>>>
>>>> Hello Karsten,
>>>>
>>>> let me try to help you.
>>>> Let's start from the beginning and will not use cache for simplicity, we
>>>> can always add it later...
>>>> As I understood, you are not making http proxy, but some tunnel for
>>>> socket connections. In other words nothing http specific?
>>>>
>>>> So I would advice you to start implementing something called... let's
>>>> say ProxyProtocolFilter (as Jeanfrancois proposed) :)
>>>> To see how you can implement the Filter - please find EchoFilter in
>>>> Grizzly/framework test folder.
>>>>
>>>> As for proxy-to-tomcat connections - please use ConnectorHandlers (to
>>>> get one use controller.aquireConnectorHandler(), and don't forget to
>>>> release it).
>>>> We're working on documentations, but you can take a look at unit tests
>>>> we have to understand how you can use Grizzly both for client and server
>>>> sides.
>>>>
>>>> If you'll have questions - please ask.
>>>>
>>> OK, I have a ProxyProtocolFilter and I also found out that the
>>> WorkerThread contains the ByteBuffer. So I would do the following
>>>
>>> Use the returned ByteBuffer from the WorkerThread aquire a
>>> TCPConnectorHandler from the Controller in the Context
>>>
>>> register a CallBackHandler with a reference to the SocketConnection for
>>> the way from client to proxy and an implemented onConnect() method
>>>
>>> write out the data with write(byteBuffer, true)
>>>
>>> When do I release the TCPConnectorHandler? I store the TCPConnector with
>>> the SocketChannel for the way client-proxy in a Map in the Context. So
>>> the connection can be reused. What is better?
>>>
>>> When the connection is done onConnect gets executed and I can get the
>>> SocketChannel for the line proxy - Tomcat server
>>> The pair of SocketConnections client-proxy and proxy-Tomcat server is
>>> kept in a mapping in the context. This is important to remember who is
>>> talking over the proxy to whom.
>>>
>>> For the way server-proxy to proxy-client I have to write back the data.
>>> Problem I see no way how I can use here an TCPConnectorHandler. The
>>> TCPSelectorHandler offers no possibility to use an existing
>>> SocketChannel. I would change this to simplify my life or how is it
>>> intended?
>>>
>>> Why are there two methods: register(CallbackHandler) and
>>> setCallbackHandler(...)?
>>>
>>> Thanks,
>>> Karsten
>>>
>>>
>>>> WBR,
>>>> Alexey.
>>>>
>>>> Karsten Ohme wrote:
>>>>
>>>>> On Thu, May 31, 2007 at 02:43:43PM -0400, Jeanfrancois Arcand wrote:
>>>>>
>>>>>
>>>>>> Hi Karsten,
>>>>>>
>>>>>> don't stop the feedback!
>>>>>>
>>>>>> Karsten Ohme wrote:
>>>>>>
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I want to program a proxy (actually tunnel). All connections are made
>>>>>>> to the proxy, the proxy makes some decisions and forwards them to the
>>>>>>> server. For my situation many clients connect to the proxy on port 80,
>>>>>>> the proxy forwards the requests to a Tomcat server on port 8080 and
>>>>>>> writes the response back to the client.
>>>>>>>
>>>>>>>
>>>>>> Stupid question: can the client connect directly to Tomcat or does all
>>>>>> connection must go to the proxy? I suspect all connections have to pass
>>>>>> through the proxy, but in case not, the proxy can always send a
>>>>>> redirect to the client (using the location: header).
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> How can I acieve this with Grizzly? I though I had to extend the
>>>>>>> TCPSelectorHandler, overwrite the onAcceptInterest method, establish
>>>>>>> there a new TCPConnectorHandler for the path client-proxy and one for
>>>>>>> proxy-server and register CallbackHandlers wo propagate the read and
>>>>>>> write operations.
>>>>>>>
>>>>>>>
>>>>>> I would not override the onAcceptInterest but instead let the default
>>>>>> workflow happen. On of the reason is onAcceptInterest is executed on
>>>>>> the same thread as the Selector.select(), which is a performance
>>>>>> bottleneck. I would instead implement two ProtocolFilters that uses the
>>>>>> newly added ConnectionPool/Cache. My recommendation is to do:
>>>>>>
>>>>>> 1. Use the default ReadFilter to execute the first read to make sure
>>>>>> the connection hasn't been closed between the accept() and the first
>>>>>> read.
>>>>>> 2. Add a new ProxyProtocolFilter:
>>>>>>
>>>>>> + When initializing, create a pool of connection your remote server
>>>>>> (Tomcat). I recommend you take a look at the new ConnectionPool/Cache
>>>>>> Alexey demonstrated yesterday at the Grizzly meeting.
>>>>>>
>>>>>>
>>>>> I don't know how to use it. What is a ConnectionPool? There is only a
>>>>> class ConnectionCache. What is it useful for? From the name I suspect
>>>>> that some sort of connections are cached and I have a method to get free
>>>>> connections which I can use. I would expect a constructor with a given
>>>>> number where this amount of connections are created. For me this would
>>>>> be always the same type of connection from the proxy to the client, for
>>>>> the way
>>>>>
>>>> >from client to proxy I need for each client a single connection or not?
>>>>
>>>>> What are doing requestReceived(), requestProcessed() and responseSent( C
>>>>> conn ). Which connection I have to pass in as parameter? What means
>>>>> cached? In the sources it looks like i have to pass the connectiosn on
>>>>> my own. From which class must the methods be called? How can I reuese
>>>>> such a cached exception when it is idle? There is not get method.
>>>>>
>>>>> Regards,
>>>>> Karsten
>>>>>
>>>>>
>>>>>
>>>>>> + When execute() is invoked, use a StreamAlgorithm implementation to
>>>>>> make sure you can read the complete HTTP request (note: you gonna need
>>>>>> to buffer the body as well). The module/http sub module have a
>>>>>> StreamAlgorithm implementations called
>>>>>> ContentLengthAlgorithm|StateMachineAlgoruithm that can be reused.
>>>>>> Mainly those classes will make sure the entire headers + body are read.
>>>>>> + Once you have read all the bytes, get a connection from the
>>>>>> connection pool and flush the bytes to Tomcat. Make the
>>>>>> TCPConnectionHandler.write(bb,TRUE) so the temporary Selector trick can
>>>>>> be reused.
>>>>>> + Then read back the response and flush it back to the client.
>>>>>>
>>>>>> Would that make sense? You might also want to create two
>>>>>> ProtocolFilter, one for reading the request, and one for writing the
>>>>>> response to the active connection to Tomcat.
>>>>>>
>>>>>>
>>>>>>
>>>>>>> But I don't know how the ProtocolFilter fits into the picture. How do
>>>>>>> I use it? I also want to use TLS connections. How can I get the data
>>>>>>> which is decoded?
>>>>>>>
>>>>>>> Is there any documentation or tutorial for the new Grizzly API?
>>>>>>>
>>>>>>>
>>>>>> Take a look at the following talks:
>>>>>>
>>>>>> https://grizzly.dev.java.net/presentations/FISL-2007.pdf
>>>>>> http://weblogs.java.net/blog/jfarcand/archive/BOF-4989-Grizzly.pdf
>>>>>>
>>>>>> We don't have yet tutorials but I'm working on one right now.
>>>>>>
>>>>>> Hope that help.
>>>>>>
>>>>>> -- Jeanfrancois
>>>>>>
>>>>>>
>>>>>>
>>>>>>> Regards,
>>>>>>> Karsten
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>>
>>>>>>
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>>
>>>>>
>>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>>
>>>
>
>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>> ------------------------------------------------------------------------
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net