Thank you for the update, Sam!
Yes, you're absolutely right. In case you'll want to have SSL-to-peer
part, you'll need to perform SSL handshaking and prepare SSL streams,
like in sample [1].
WBR,
Alexey.
[1]
https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/samples/framework-samples/src/main/java/com/sun/grizzly/samples/ssl/
On Sep 25, 2009, at 16:26 , Sam Crawford wrote:
> Nevermind, I think I've cracked this one myself.
>
> Because the connected() method is called on the filters within the
> transport making the peer connection, we can obtain the context at the
> point of connection (before any data is read/written) and then place
> the StreamReader and StreamWriter (which have already been wrapped by
> SSLFilter at that point) somewhere easily accessible later on.
>
> I'll post some sample code when I'm all done, and hopefully someone
> will see what I'm rabbiting on about!
>
> Thanks,
>
> Sam
>
>
> 2009/9/24 samcrawford <samcrawford_at_gmail.com>:
>> Alexey (and others!),
>>
>> I'm currently trying to add in SSL support to my tunneling mechanism.
>> The idea is to be able to handle any combination of SSL and
>> plaintext,
>> namely:
>>
>> 1. Plaintext to tunnel, plaintext to peer (as per Alexey's original
>> example)
>> 2. Plaintext to tunnel, SSL to peer
>> 3. SSL to tunnel, plaintext to peer
>> 4. SSL to tunnel, SSL to peer
>>
>> I'm using the SSLFilter to manage the process of sending/receiving
>> SSL
>> traffic, and whilst I have it working in some simple cases, I've run
>> into a bit of a design roadblock.
>>
>> Referring back to Alexey's original tunnel demo code, the
>> redirectToPeer method just obtains a StreamReader from the incoming
>> connection, and passes that to the writeStream method on the
>> StreamWriter of the peer connection. Whilst this is fine in plaintext
>> land, it doesn't work for SSL. I believe this to be because I need to
>> obtain the StreamReader and StreamWriter from the context (i.e. after
>> the SSLFilter has done it's job) rather than the connection - some
>> testing suggests this is indeed the case.
>>
>> Whilst it's easy enough to grab the StreamReader from the context of
>> the incoming connection, we don't have a context for the outgoing
>> (peer) connection, so can't push that through the SSL filter. This
>> creates an issue with cases #2 and #4 above, where writing to
>> Connection.getStreamWriter() is insufficient.
>>
>> I'm not sure if it's valid for me to store a reference to the
>> StreamReader & StreamWriter in an attribute (as the current
>> connection
>> map is maintained), but even if it were, on the first bit of data
>> sent
>> from client > server I wouldn't have a handle to the StreamWriter on
>> the peer.
>>
>> Is there something simple I'm missing here, or have I confused
>> everyone completely?
>>
>> Thanks,
>>
>> Sam
>>
>>
>>
>> 2009/9/1 Sam Crawford <samcrawford_at_gmail.com>:
>>> Thanks v much Alexey. I'll proceed along my current course, but will
>>> push new connections into a DelayedQueue, and then have a single
>>> separate ScheduledExecutor dequeuing items after 5 seconds and
>>> checking the handshake status.
>>>
>>> Rest assured I'll be back with more questions on other matters soon!
>>>
>>> All the best,
>>>
>>> Sam
>>>
>>>
>>> 2009/9/1 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
>>>> Hi Sam,
>>>>
>>>> I think you're doing that right way!
>>>> Because handshake you're running is a quite complex process (with
>>>> several
>>>> reads/writes as I understand), which is specific to your
>>>> protocol, so not
>>>> sure Grizzly can have some general solution for this.
>>>> We have IdleTimeoutFilter implementation, which closes Connection
>>>> after
>>>> detecting that it is idle for some period of time, but it's not
>>>> applicable
>>>> for you, because you want to detect handshake timeouts.
>>>>
>>>> So, IMHO, what you are proposing is right way to implement the
>>>> logic you
>>>> need.
>>>>
>>>> Thanks.
>>>>
>>>> WBR,
>>>> Alexey.
>>>>
>>>>> Adding the following to handleAccept in the filter does what I
>>>>> want,
>>>>> but it doesn't seem very modern! I'm going to explore using the
>>>>> ScheduledExecutorService, but would still be interested to know if
>>>>> there's a proper grizzly way of doing this.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Sam
>>>>>
>>>>>
>>>>> Thread r = new Thread() {
>>>>> public void run() {
>>>>> try {
>>>>> Thread.sleep(5000);
>>>>> // ctx.getConnection() is still null in
>>>>> handleAccept...
>>>>> Connection conn =
>>>>> ctx.getProcessorRunnable().getConnection();
>>>>> TunnelHandshake handshake =
>>>>> handshakeAttribute.get(conn);
>>>>> if (handshake == null || !
>>>>> handshake.isComplete()) {
>>>>> System.out.println("Closing
>>>>> connection");
>>>>> conn.close();
>>>>> }
>>>>> } catch (Exception e) {
>>>>> e.printStackTrace();
>>>>> }
>>>>> }
>>>>> };
>>>>> r.start();
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 2009/9/1 Sam Crawford <samcrawford_at_gmail.com>:
>>>>>>
>>>>>> Hi Alexey,
>>>>>>
>>>>>> Thanks, but I recognise already that we don't need to block for
>>>>>> operations. I've had great success with getting the non-blocking
>>>>>> aspect working well!
>>>>>>
>>>>>> My question was around creating time limits for logical steps of
>>>>>> execution (not physical timeouts when reading from a blocking
>>>>>> socket!). So my handshaking process completes in a non-blocking
>>>>>> manner, but I want to enforce an absolute time limit of 5
>>>>>> seconds that
>>>>>> the handshake can take.
>>>>>>
>>>>>> To be specific:
>>>>>>
>>>>>> 1. If the client connects but does not transfer any bytes then
>>>>>> the
>>>>>> connection should be dropped after 5 seconds
>>>>>> 2. If the client connects and starts the handshake, but does not
>>>>>> complete it within 5 seconds, then the connection should be
>>>>>> dropped
>>>>>> 3. If the client connects, completes the handshake within 5
>>>>>> seconds,
>>>>>> and establishes the tunnel then there should not be an enforced
>>>>>> timeout
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Sam
>>>>>>
>>>>>>
>>>>>> 2009/9/1 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
>>>>>>>
>>>>>>> Hi Sam,
>>>>>>>
>>>>>>>> Apologies for the slow reply. There was no issues with the
>>>>>>>> tunneling
>>>>>>>> when the exception was thrown, so I'm not concerned about it.
>>>>>>>>
>>>>>>>> I'm now actively working on porting our project to use
>>>>>>>> Grizzly (and I
>>>>>>>> will certainly write an article afterwards to cover my
>>>>>>>> experiences!),
>>>>>>>> and have another query...
>>>>>>>>
>>>>>>>> Our tunneling mechanism uses a handshaking mechanism (not
>>>>>>>> unlike a
>>>>>>>> SOCKS proxy with the CONNECT header). We don't want to wait
>>>>>>>> indefinitely for the handshake to complete (e.g. 5 seconds is
>>>>>>>> probably
>>>>>>>> a sensible maximum). That said, once the tunnel is running,
>>>>>>>> we would
>>>>>>>> not want to have any timeouts (i.e. the tunnel should be able
>>>>>>>> to sit
>>>>>>>> idle for hours if need be).
>>>>>>>>
>>>>>>>> In the old Java sockets API I'd set a read timeout on the
>>>>>>>> socket
>>>>>>>> before doing the handshaking, and remove it afterwards.
>>>>>>>>
>>>>>>>> I can't see how to achieve the same (or similar) in Grizzly
>>>>>>>> 2.0. Is
>>>>>>>> there a recommended way of doing this?
>>>>>>>
>>>>>>> By default all the I/O operations on Grizzly 2.0 TCP NIO
>>>>>>> connections are
>>>>>>> non-blocking.
>>>>>>> You have Grizzly Connection object, which represents your
>>>>>>> network
>>>>>>> connection
>>>>>>> [1]. You can get StreamReader, StreamWriter out of this
>>>>>>> Connection.
>>>>>>>
>>>>>>> Using StreamReader [2] you can check number of bytes available
>>>>>>> for
>>>>>>> reading:
>>>>>>> StreamReader.availableDataSize() or retrieve/register some
>>>>>>> notifier,
>>>>>>> which
>>>>>>> will notify you, when StreamReader state will be changed: new
>>>>>>> bytes
>>>>>>> become
>>>>>>> available, connection was closed etc:
>>>>>>> Future f = StreamReader.notifyAvailable(numberOfBytes,
>>>>>>> [completionHandler]);
>>>>>>>
>>>>>>> Using StreamWriter [3] you can perform write operations in non-
>>>>>>> blocking
>>>>>>> mode, using StreamWriter.writeXXX(...). By calling
>>>>>>> Future f = StreamReader.flush([completionHandler]);
>>>>>>> you can register/retrieve notifier, using which you can
>>>>>>> asynchronously
>>>>>>> check
>>>>>>> write operation completion state.
>>>>>>>
>>>>>>> So, really, you don't to block for anything :)
>>>>>>>
>>>>>>> Please let me know, if you'll have any questions.
>>>>>>>
>>>>>>> WBR,
>>>>>>> Alexey.
>>>>>>>
>>>>>>>
>>>>>>> [1]
>>>>>>>
>>>>>>> https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/modules/grizzly/src/main/java/com/sun/grizzly/Connection.java?rev=3266&view=markup
>>>>>>> [2]
>>>>>>>
>>>>>>> https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/modules/grizzly/src/main/java/com/sun/grizzly/streams/StreamReader.java?rev=3292&view=markup
>>>>>>> [3]
>>>>>>>
>>>>>>> https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/modules/grizzly/src/main/java/com/sun/grizzly/streams/StreamWriter.java?rev=3496&view=markup
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks again,
>>>>>>>>
>>>>>>>> Sam
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 2009/8/18 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
>>>>>>>>>
>>>>>>>>> Hi Sam,
>>>>>>>>>
>>>>>>>>>> I've fired up the example you provided and it seems pretty
>>>>>>>>>> straightforward and works well.
>>>>>>>>>>
>>>>>>>>>> However, when doing some quick tests via it I noted the
>>>>>>>>>> following
>>>>>>>>>> exception was printed every so often... Is this something
>>>>>>>>>> to be
>>>>>>>>>> concerned about? I was running this with the latest 2.0
>>>>>>>>>> SNAPSHOT.
>>>>>>>>>
>>>>>>>>> Hmm, I think you can say me, if it's something you have
>>>>>>>>> concerns about
>>>>>>>>> :))))
>>>>>>>>> For me it looks like issue occurs, when Filter decides to
>>>>>>>>> close one
>>>>>>>>> connection, it also closes a peer connection. And closing of
>>>>>>>>> peer
>>>>>>>>> connection
>>>>>>>>> may cause this exception.
>>>>>>>>>
>>>>>>>>> Do you see any problem with tunneling functionality, when the
>>>>>>>>> exception
>>>>>>>>> occurs?
>>>>>>>>>
>>>>>>>>> I will probably reduce the logging level for the exception.
>>>>>>>>>
>>>>>>>>> Thank you.
>>>>>>>>>
>>>>>>>>> WBR,
>>>>>>>>> Alexey.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks
>>>>>>>>>>
>>>>>>>>>> Sam
>>>>>>>>>>
>>>>>>>>>> # java -cp "grizzly-framework-2.0.0-SNAPSHOT.jar:."
>>>>>>>>>> com.sun.grizzly.samples.tunnel.TunnelServer
>>>>>>>>>> Aug 16, 2009 9:33:31 PM
>>>>>>>>>> com.sun.grizzly.samples.tunnel.TunnelServer
>>>>>>>>>> main
>>>>>>>>>> INFO: Press any key to stop the server...
>>>>>>>>>> Aug 16, 2009 9:33:36 PM
>>>>>>>>>> com.sun.grizzly.nio.transport.TCPNIOTransport
>>>>>>>>>> fireIOEvent
>>>>>>>>>> WARNING: Unexpected exception occurred
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> fireIOEvent
>>>>>>>>>> ().connection
>>>>>>>>>> =com.sun.grizzly.nio.transport.TCPNIOConnection_at_785f8172
>>>>>>>>>> event=READ
>>>>>>>>>> java.nio.channels.CancelledKeyException
>>>>>>>>>> at
>>>>>>>>>> sun
>>>>>>>>>> .nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:
>>>>>>>>>> 55)
>>>>>>>>>> at
>>>>>>>>>> sun
>>>>>>>>>> .nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:
>>>>>>>>>> 64)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .DefaultSelectorHandler
>>>>>>>>>> .unregisterKey0(DefaultSelectorHandler.java:216)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .DefaultSelectorHandler
>>>>>>>>>> .unregisterKey(DefaultSelectorHandler.java:104)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .AbstractNIOConnection
>>>>>>>>>> .disableIOEvent(AbstractNIOConnection.java:271)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .transport
>>>>>>>>>> .TCPNIOTransport
>>>>>>>>>> .executeDefaultProcessor(TCPNIOTransport.java:730)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .transport
>>>>>>>>>> .TCPNIOTransport.processReadIoEvent(TCPNIOTransport.java:703)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio
>>>>>>>>>> .transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:
>>>>>>>>>> 648)
>>>>>>>>>> at
>>>>>>>>>> com.sun.grizzly.nio.SelectorRunner.fire(SelectorRunner.java:
>>>>>>>>>> 385)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly
>>>>>>>>>> .nio.SelectorRunner.iterateKeyEvents(SelectorRunner.java:317)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly.nio.SelectorRunner.iterateKeys(SelectorRunner.java:
>>>>>>>>>> 287)
>>>>>>>>>> at
>>>>>>>>>> com
>>>>>>>>>> .sun
>>>>>>>>>> .grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:259)
>>>>>>>>>> at
>>>>>>>>>> com.sun.grizzly.nio.SelectorRunner.run(SelectorRunner.java:
>>>>>>>>>> 190)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> java.util.concurrent.ThreadPoolExecutor
>>>>>>>>>> $Worker.runTask(ThreadPoolExecutor.java:886)
>>>>>>>>>> at
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> java.util.concurrent.ThreadPoolExecutor
>>>>>>>>>> $Worker.run(ThreadPoolExecutor.java:908)
>>>>>>>>>> at java.lang.Thread.run(Thread.java:619)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2009/8/12 Sam Crawford <samcrawford_at_gmail.com>:
>>>>>>>>>>>
>>>>>>>>>>> Brilliant, thank you very much! Hopefully I'll get started
>>>>>>>>>>> on this
>>>>>>>>>>> next month and you'll no doubt see me posting lots of
>>>>>>>>>>> questions
>>>>>>>>>>> here.
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>>
>>>>>>>>>>> Sam
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 2009/8/11 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
>>>>>>>>>>>>
>>>>>>>>>>>> Hi Sam,
>>>>>>>>>>>>
>>>>>>>>>>>>> I'm currently looking to rewrite our (blocking)
>>>>>>>>>>>>> tunneling software
>>>>>>>>>>>>> using NIO (in an effort to increase scalability), and
>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>> seems
>>>>>>>>>>>>> like it could save me a considerable amount of time. To
>>>>>>>>>>>>> be clear,
>>>>>>>>>>>>> this
>>>>>>>>>>>>> is for tunneling arbitrary TCP traffic (not just HTTP!),
>>>>>>>>>>>>> over both
>>>>>>>>>>>>> SSL
>>>>>>>>>>>>> and non-SSL.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Having searched the archives, I see that someone else
>>>>>>>>>>>>> two years
>>>>>>>>>>>>> was
>>>>>>>>>>>>> interested in something similar
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> (https://grizzly.dev.java.net/servlets/ReadMsg?listName=users&msgNo=52
>>>>>>>>>>>>> ).
>>>>>>>>>>>>> Are the concepts largely the same nowadays? I know the
>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>> libraries have progressed a great deal since then, so I
>>>>>>>>>>>>> didn't
>>>>>>>>>>>>> want
>>>>>>>>>>>>> to
>>>>>>>>>>>>> dive too deeply into that if there were more appropriate
>>>>>>>>>>>>> ways of
>>>>>>>>>>>>> achieving this these days.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Any other pointers would be most welcome!
>>>>>>>>>>>>
>>>>>>>>>>>> IMHO it should be pretty easy to write simple tunneling
>>>>>>>>>>>> application.
>>>>>>>>>>>> All you'll need on server side - is to build filter chain
>>>>>>>>>>>> and keep
>>>>>>>>>>>> client<->server connection map to redirect data among them.
>>>>>>>>>>>>
>>>>>>>>>>>> I've just created simple tunnel example for Grizzly 2.0,
>>>>>>>>>>>> hope it
>>>>>>>>>>>> will
>>>>>>>>>>>> help.
>>>>>>>>>>>> To build them - please use the latest Grizzly 2.0
>>>>>>>>>>>> snapshot [2]
>>>>>>>>>>>>
>>>>>>>>>>>> WBR,
>>>>>>>>>>>> Alexey.
>>>>>>>>>>>>
>>>>>>>>>>>> [1]
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> https://grizzly.dev.java.net/source/browse/grizzly/branches/2dot0/code/samples/framework-samples/src/main/java/com/sun/grizzly/samples/tunnel/
>>>>>>>>>>>> [2]
>>>>>>>>>>>> <groupId>com.sun.grizzly</groupId>
>>>>>>>>>>>> <artifactId>grizzly-framework</artifactId>
>>>>>>>>>>>> <version>2.0.0-SNAPSHOT</version>
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Many thanks,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sam
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>>>>> 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
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> 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
>