"Unconnected sockets not implemented" using Commons Net ftps support

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

"Unconnected sockets not implemented" using Commons Net ftps support

Bengt Rodehav
Hello,

I'm using Apache Camel as an integration platform. Specifically, at the
moment, I depend on the ftp/ftps/sftp support in the camel-ftp component.
Under the hood Camel uses Commons Net for ftp and ftps support.

Recently, the camel-ftp component was enhanced (on my request) with the
possibility to use a secure data channel. This is accomplished by using the
execProt() (and execPsbz()) method in class FTPSClient. Unfortunately the
execProt() method also sets the FTPSClient's socket factory to a new
instance of FTPSSocketFactory. I'm sure there is a good reason for this that
I'm not aware of.

However, later on (in case Camel needs to reconnect), one of the connect()
methods in SocketClient (the ultimate base class of FTPSClient) is called.
Unfortunately all the connect methods first create an unconnected socket and
then tries to connect it. The connection factory now associated with the
FTPSClient the throws an exception stating that "Unconnected sockets not
implemented".

I've looked at the source code in commons-net trying to find out what's
happening. These are my findings:

The FTPSSocketFactory class override the createSocket() methods in
SocketFactory and delegates them to its SSLContext's socket factory. Thus
it's the SSLContext's connection factory that is being used.

Since we are able to initially connect (the problems are related to
reconnecting using the same FTPSClient instance) we need to investigate
exactly what execProt() does that makes further connection attempts to fail.

Lets have a look at the FTPSClient class. When the initial connection is up,
the _connectAction() method is called. It in turn calls sslNegotiation()
which in turn sets up the secure socket. In the sslNegotiation() method, an
SSLSocketFactory is not instantiated directly. It is given by the
SSLContext's getSocketFactory() method. This connection factory obviously
works otherwise the secure connection wouldn't work even initially.

Compare this with what's being done in the execProt() method. Here the
FTPSSocketFactory is instantiated directly with the SSLContext passed as a
constructor argument. Obviously this factory does NOT work...

A question that comes to mind is why the socket factory created in the
sslNegotiation() method is NOT set as the SocketClient's socket factory but
the one created in the execProt() method is? It turns out that execProt()
calls a generic sendCommand() method that sends the command and if the reply
is OK, then sets the socket factory to null! One wonders why (and there is
also a comment in the code: "Check this - is this necessary at all?")?
Anyway, this is probably the reason why execProt() needs to "reset" the
connection factory.

Can anyone help me out with this? I need to get ftps (with a secure data
channel) working in Camel.

Is it a bug in the FTPSClient class or are we using it the wrong way? Should
it be possible to reuse an instance of FTPSClient or must a new FTPSClient
instance be created on every reconnect?

/Bengt
Reply | Threaded
Open this post in threaded view
|

Re: "Unconnected sockets not implemented" using Commons Net ftps support

Bengt Rodehav
Does no one have any ideas about this?

When looking more closely at the FTPSClient class, it does not seem like it
can be re-used across multiple connections once it has established a secure
data channel. In contrast, the parent class, FTPClient, has a disconnect()
method that can be used to get rid of the current connection in order to be
able to make a new connection attempt. The disconnect() method is not
overridden in FTPSClient and thus does not do the necessary cleanup.

I think that either the FTPSClient must be made revoverable/reusable similar
to the FTPClient or it must clearly be stated that new instances of
FTPSClient must be instantiated for every new connection attempt. In the
latter case, the connect() methods should throw an exception indicating that
a connect() is not possible under these circumstances
(IllegalStateException?). Needless to say, I vote for the former.

/Bengt





2010/6/17 Bengt Rodehav <[hidden email]>

> Hello,
>
> I'm using Apache Camel as an integration platform. Specifically, at the
> moment, I depend on the ftp/ftps/sftp support in the camel-ftp component.
> Under the hood Camel uses Commons Net for ftp and ftps support.
>
> Recently, the camel-ftp component was enhanced (on my request) with the
> possibility to use a secure data channel. This is accomplished by using the
> execProt() (and execPsbz()) method in class FTPSClient. Unfortunately the
> execProt() method also sets the FTPSClient's socket factory to a new
> instance of FTPSSocketFactory. I'm sure there is a good reason for this
> that I'm not aware of.
>
> However, later on (in case Camel needs to reconnect), one of the connect()
> methods in SocketClient (the ultimate base class of FTPSClient) is called.
> Unfortunately all the connect methods first create an unconnected socket and
> then tries to connect it. The connection factory now associated with the
> FTPSClient the throws an exception stating that "Unconnected sockets not
> implemented".
>
> I've looked at the source code in commons-net trying to find out what's
> happening. These are my findings:
>
>  The FTPSSocketFactory class override the createSocket() methods in
> SocketFactory and delegates them to its SSLContext's socket factory. Thus
> it's the SSLContext's connection factory that is being used.
>
> Since we are able to initially connect (the problems are related to
> reconnecting using the same FTPSClient instance) we need to investigate
> exactly what execProt() does that makes further connection attempts to fail.
>
> Lets have a look at the FTPSClient class. When the initial connection is
> up, the _connectAction() method is called. It in turn calls sslNegotiation()
> which in turn sets up the secure socket. In the sslNegotiation() method, an
> SSLSocketFactory is not instantiated directly. It is given by the
> SSLContext's getSocketFactory() method. This connection factory obviously
> works otherwise the secure connection wouldn't work even initially.
>
> Compare this with what's being done in the execProt() method. Here the
> FTPSSocketFactory is instantiated directly with the SSLContext passed as a
> constructor argument. Obviously this factory does NOT work...
>
> A question that comes to mind is why the socket factory created in the
> sslNegotiation() method is NOT set as the SocketClient's socket factory but
> the one created in the execProt() method is? It turns out that execProt()
> calls a generic sendCommand() method that sends the command and if the reply
> is OK, then sets the socket factory to null! One wonders why (and there is
> also a comment in the code: "Check this - is this necessary at all?")?
> Anyway, this is probably the reason why execProt() needs to "reset" the
> connection factory.
>
> Can anyone help me out with this? I need to get ftps (with a secure data
> channel) working in Camel.
>
> Is it a bug in the FTPSClient class or are we using it the wrong way?
> Should it be possible to reuse an instance of FTPSClient or must a new
> FTPSClient instance be created on every reconnect?
>
> /Bengt
>
>
Reply | Threaded
Open this post in threaded view
|

Re: "Unconnected sockets not implemented" using Commons Net ftps support

sebb-2-2
On 18/06/2010, Bengt Rodehav <[hidden email]> wrote:
> Does no one have any ideas about this?

There was a similar error reported in JMeter a while ago.
[And indeed many other applications]

It was caused by a change in Java 1.6 in the way that the sockets
are created which meant that some SSL Socket factory implementations
no longer worked.

See if you get the same problem with Java 1.5.

If not, then the relevant socket factory needs updating.

>  When looking more closely at the FTPSClient class, it does not seem like it
>  can be re-used across multiple connections once it has established a secure
>  data channel. In contrast, the parent class, FTPClient, has a disconnect()
>  method that can be used to get rid of the current connection in order to be
>  able to make a new connection attempt. The disconnect() method is not
>  overridden in FTPSClient and thus does not do the necessary cleanup.
>
>  I think that either the FTPSClient must be made revoverable/reusable similar
>  to the FTPClient or it must clearly be stated that new instances of
>  FTPSClient must be instantiated for every new connection attempt. In the
>  latter case, the connect() methods should throw an exception indicating that
>  a connect() is not possible under these circumstances
>  (IllegalStateException?). Needless to say, I vote for the former.
>
>  /Bengt
>
>
>
>
>
>  2010/6/17 Bengt Rodehav <[hidden email]>
>
>
>  > Hello,
>  >
>  > I'm using Apache Camel as an integration platform. Specifically, at the
>  > moment, I depend on the ftp/ftps/sftp support in the camel-ftp component.
>  > Under the hood Camel uses Commons Net for ftp and ftps support.
>  >
>  > Recently, the camel-ftp component was enhanced (on my request) with the
>  > possibility to use a secure data channel. This is accomplished by using the
>  > execProt() (and execPsbz()) method in class FTPSClient. Unfortunately the
>  > execProt() method also sets the FTPSClient's socket factory to a new
>  > instance of FTPSSocketFactory. I'm sure there is a good reason for this
>  > that I'm not aware of.
>  >
>  > However, later on (in case Camel needs to reconnect), one of the connect()
>  > methods in SocketClient (the ultimate base class of FTPSClient) is called.
>  > Unfortunately all the connect methods first create an unconnected socket and
>  > then tries to connect it. The connection factory now associated with the
>  > FTPSClient the throws an exception stating that "Unconnected sockets not
>  > implemented".
>  >
>  > I've looked at the source code in commons-net trying to find out what's
>  > happening. These are my findings:
>  >
>  >  The FTPSSocketFactory class override the createSocket() methods in
>  > SocketFactory and delegates them to its SSLContext's socket factory. Thus
>  > it's the SSLContext's connection factory that is being used.
>  >
>  > Since we are able to initially connect (the problems are related to
>  > reconnecting using the same FTPSClient instance) we need to investigate
>  > exactly what execProt() does that makes further connection attempts to fail.
>  >
>  > Lets have a look at the FTPSClient class. When the initial connection is
>  > up, the _connectAction() method is called. It in turn calls sslNegotiation()
>  > which in turn sets up the secure socket. In the sslNegotiation() method, an
>  > SSLSocketFactory is not instantiated directly. It is given by the
>  > SSLContext's getSocketFactory() method. This connection factory obviously
>  > works otherwise the secure connection wouldn't work even initially.
>  >
>  > Compare this with what's being done in the execProt() method. Here the
>  > FTPSSocketFactory is instantiated directly with the SSLContext passed as a
>  > constructor argument. Obviously this factory does NOT work...
>  >
>  > A question that comes to mind is why the socket factory created in the
>  > sslNegotiation() method is NOT set as the SocketClient's socket factory but
>  > the one created in the execProt() method is? It turns out that execProt()
>  > calls a generic sendCommand() method that sends the command and if the reply
>  > is OK, then sets the socket factory to null! One wonders why (and there is
>  > also a comment in the code: "Check this - is this necessary at all?")?
>  > Anyway, this is probably the reason why execProt() needs to "reset" the
>  > connection factory.
>  >
>  > Can anyone help me out with this? I need to get ftps (with a secure data
>  > channel) working in Camel.
>  >
>  > Is it a bug in the FTPSClient class or are we using it the wrong way?
>  > Should it be possible to reuse an instance of FTPSClient or must a new
>  > FTPSClient instance be created on every reconnect?
>  >
>  > /Bengt
>  >
>  >
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: "Unconnected sockets not implemented" using Commons Net ftps support

Bengt Rodehav
Thank you for your reply Sebb!

I've now tested with Java 1.5.0_22 and I still get the "Unconnected
sockets..." exception.

Any ideas?

Do you know if it should be possible to re-use an instance of FTPSClient?
The situation we have in camel-ftp is that the ftps connection is
disconnected due to an error. Shall it be possible to use the same
FTPSClient instance again and call the connect() method? Looking through the
code, the FTPSClient looks very stateful and I can't see how it can be
"reset".

/Bengt

2010/6/18 sebb <[hidden email]>

> On 18/06/2010, Bengt Rodehav <[hidden email]> wrote:
> > Does no one have any ideas about this?
>
> There was a similar error reported in JMeter a while ago.
> [And indeed many other applications]
>
> It was caused by a change in Java 1.6 in the way that the sockets
> are created which meant that some SSL Socket factory implementations
> no longer worked.
>
> See if you get the same problem with Java 1.5.
>
> If not, then the relevant socket factory needs updating.
>
> >  When looking more closely at the FTPSClient class, it does not seem like
> it
> >  can be re-used across multiple connections once it has established a
> secure
> >  data channel. In contrast, the parent class, FTPClient, has a
> disconnect()
> >  method that can be used to get rid of the current connection in order to
> be
> >  able to make a new connection attempt. The disconnect() method is not
> >  overridden in FTPSClient and thus does not do the necessary cleanup.
> >
> >  I think that either the FTPSClient must be made revoverable/reusable
> similar
> >  to the FTPClient or it must clearly be stated that new instances of
> >  FTPSClient must be instantiated for every new connection attempt. In the
> >  latter case, the connect() methods should throw an exception indicating
> that
> >  a connect() is not possible under these circumstances
> >  (IllegalStateException?). Needless to say, I vote for the former.
> >
> >  /Bengt
> >
> >
> >
> >
> >
> >  2010/6/17 Bengt Rodehav <[hidden email]>
> >
> >
> >  > Hello,
> >  >
> >  > I'm using Apache Camel as an integration platform. Specifically, at
> the
> >  > moment, I depend on the ftp/ftps/sftp support in the camel-ftp
> component.
> >  > Under the hood Camel uses Commons Net for ftp and ftps support.
> >  >
> >  > Recently, the camel-ftp component was enhanced (on my request) with
> the
> >  > possibility to use a secure data channel. This is accomplished by
> using the
> >  > execProt() (and execPsbz()) method in class FTPSClient. Unfortunately
> the
> >  > execProt() method also sets the FTPSClient's socket factory to a new
> >  > instance of FTPSSocketFactory. I'm sure there is a good reason for
> this
> >  > that I'm not aware of.
> >  >
> >  > However, later on (in case Camel needs to reconnect), one of the
> connect()
> >  > methods in SocketClient (the ultimate base class of FTPSClient) is
> called.
> >  > Unfortunately all the connect methods first create an unconnected
> socket and
> >  > then tries to connect it. The connection factory now associated with
> the
> >  > FTPSClient the throws an exception stating that "Unconnected sockets
> not
> >  > implemented".
> >  >
> >  > I've looked at the source code in commons-net trying to find out
> what's
> >  > happening. These are my findings:
> >  >
> >  >  The FTPSSocketFactory class override the createSocket() methods in
> >  > SocketFactory and delegates them to its SSLContext's socket factory.
> Thus
> >  > it's the SSLContext's connection factory that is being used.
> >  >
> >  > Since we are able to initially connect (the problems are related to
> >  > reconnecting using the same FTPSClient instance) we need to
> investigate
> >  > exactly what execProt() does that makes further connection attempts to
> fail.
> >  >
> >  > Lets have a look at the FTPSClient class. When the initial connection
> is
> >  > up, the _connectAction() method is called. It in turn calls
> sslNegotiation()
> >  > which in turn sets up the secure socket. In the sslNegotiation()
> method, an
> >  > SSLSocketFactory is not instantiated directly. It is given by the
> >  > SSLContext's getSocketFactory() method. This connection factory
> obviously
> >  > works otherwise the secure connection wouldn't work even initially.
> >  >
> >  > Compare this with what's being done in the execProt() method. Here the
> >  > FTPSSocketFactory is instantiated directly with the SSLContext passed
> as a
> >  > constructor argument. Obviously this factory does NOT work...
> >  >
> >  > A question that comes to mind is why the socket factory created in the
> >  > sslNegotiation() method is NOT set as the SocketClient's socket
> factory but
> >  > the one created in the execProt() method is? It turns out that
> execProt()
> >  > calls a generic sendCommand() method that sends the command and if the
> reply
> >  > is OK, then sets the socket factory to null! One wonders why (and
> there is
> >  > also a comment in the code: "Check this - is this necessary at all?")?
> >  > Anyway, this is probably the reason why execProt() needs to "reset"
> the
> >  > connection factory.
> >  >
> >  > Can anyone help me out with this? I need to get ftps (with a secure
> data
> >  > channel) working in Camel.
> >  >
> >  > Is it a bug in the FTPSClient class or are we using it the wrong way?
> >  > Should it be possible to reuse an instance of FTPSClient or must a new
> >  > FTPSClient instance be created on every reconnect?
> >  >
> >  > /Bengt
> >  >
> >  >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: "Unconnected sockets not implemented" using Commons Net ftps support

sebb-2-2
On 18/06/2010, Bengt Rodehav <[hidden email]> wrote:
> Thank you for your reply Sebb!
>
>  I've now tested with Java 1.5.0_22 and I still get the "Unconnected
>  sockets..." exception.
>
>  Any ideas?

Sorry, no further ideas.

>  Do you know if it should be possible to re-use an instance of FTPSClient?
>  The situation we have in camel-ftp is that the ftps connection is
>  disconnected due to an error. Shall it be possible to use the same
>  FTPSClient instance again and call the connect() method? Looking through the
>  code, the FTPSClient looks very stateful and I can't see how it can be
>  "reset".
>
>  /Bengt
>
>  2010/6/18 sebb <[hidden email]>
>
>
>  > On 18/06/2010, Bengt Rodehav <[hidden email]> wrote:
>  > > Does no one have any ideas about this?
>  >
>  > There was a similar error reported in JMeter a while ago.
>  > [And indeed many other applications]
>  >
>  > It was caused by a change in Java 1.6 in the way that the sockets
>  > are created which meant that some SSL Socket factory implementations
>  > no longer worked.
>  >
>  > See if you get the same problem with Java 1.5.
>  >
>  > If not, then the relevant socket factory needs updating.
>  >
>  > >  When looking more closely at the FTPSClient class, it does not seem like
>  > it
>  > >  can be re-used across multiple connections once it has established a
>  > secure
>  > >  data channel. In contrast, the parent class, FTPClient, has a
>  > disconnect()
>  > >  method that can be used to get rid of the current connection in order to
>  > be
>  > >  able to make a new connection attempt. The disconnect() method is not
>  > >  overridden in FTPSClient and thus does not do the necessary cleanup.
>  > >
>  > >  I think that either the FTPSClient must be made revoverable/reusable
>  > similar
>  > >  to the FTPClient or it must clearly be stated that new instances of
>  > >  FTPSClient must be instantiated for every new connection attempt. In the
>  > >  latter case, the connect() methods should throw an exception indicating
>  > that
>  > >  a connect() is not possible under these circumstances
>  > >  (IllegalStateException?). Needless to say, I vote for the former.
>  > >
>  > >  /Bengt
>  > >
>  > >
>  > >
>  > >
>  > >
>  > >  2010/6/17 Bengt Rodehav <[hidden email]>
>  > >
>  > >
>  > >  > Hello,
>  > >  >
>  > >  > I'm using Apache Camel as an integration platform. Specifically, at
>  > the
>  > >  > moment, I depend on the ftp/ftps/sftp support in the camel-ftp
>  > component.
>  > >  > Under the hood Camel uses Commons Net for ftp and ftps support.
>  > >  >
>  > >  > Recently, the camel-ftp component was enhanced (on my request) with
>  > the
>  > >  > possibility to use a secure data channel. This is accomplished by
>  > using the
>  > >  > execProt() (and execPsbz()) method in class FTPSClient. Unfortunately
>  > the
>  > >  > execProt() method also sets the FTPSClient's socket factory to a new
>  > >  > instance of FTPSSocketFactory. I'm sure there is a good reason for
>  > this
>  > >  > that I'm not aware of.
>  > >  >
>  > >  > However, later on (in case Camel needs to reconnect), one of the
>  > connect()
>  > >  > methods in SocketClient (the ultimate base class of FTPSClient) is
>  > called.
>  > >  > Unfortunately all the connect methods first create an unconnected
>  > socket and
>  > >  > then tries to connect it. The connection factory now associated with
>  > the
>  > >  > FTPSClient the throws an exception stating that "Unconnected sockets
>  > not
>  > >  > implemented".
>  > >  >
>  > >  > I've looked at the source code in commons-net trying to find out
>  > what's
>  > >  > happening. These are my findings:
>  > >  >
>  > >  >  The FTPSSocketFactory class override the createSocket() methods in
>  > >  > SocketFactory and delegates them to its SSLContext's socket factory.
>  > Thus
>  > >  > it's the SSLContext's connection factory that is being used.
>  > >  >
>  > >  > Since we are able to initially connect (the problems are related to
>  > >  > reconnecting using the same FTPSClient instance) we need to
>  > investigate
>  > >  > exactly what execProt() does that makes further connection attempts to
>  > fail.
>  > >  >
>  > >  > Lets have a look at the FTPSClient class. When the initial connection
>  > is
>  > >  > up, the _connectAction() method is called. It in turn calls
>  > sslNegotiation()
>  > >  > which in turn sets up the secure socket. In the sslNegotiation()
>  > method, an
>  > >  > SSLSocketFactory is not instantiated directly. It is given by the
>  > >  > SSLContext's getSocketFactory() method. This connection factory
>  > obviously
>  > >  > works otherwise the secure connection wouldn't work even initially.
>  > >  >
>  > >  > Compare this with what's being done in the execProt() method. Here the
>  > >  > FTPSSocketFactory is instantiated directly with the SSLContext passed
>  > as a
>  > >  > constructor argument. Obviously this factory does NOT work...
>  > >  >
>  > >  > A question that comes to mind is why the socket factory created in the
>  > >  > sslNegotiation() method is NOT set as the SocketClient's socket
>  > factory but
>  > >  > the one created in the execProt() method is? It turns out that
>  > execProt()
>  > >  > calls a generic sendCommand() method that sends the command and if the
>  > reply
>  > >  > is OK, then sets the socket factory to null! One wonders why (and
>  > there is
>  > >  > also a comment in the code: "Check this - is this necessary at all?")?
>  > >  > Anyway, this is probably the reason why execProt() needs to "reset"
>  > the
>  > >  > connection factory.
>  > >  >
>  > >  > Can anyone help me out with this? I need to get ftps (with a secure
>  > data
>  > >  > channel) working in Camel.
>  > >  >
>  > >  > Is it a bug in the FTPSClient class or are we using it the wrong way?
>  > >  > Should it be possible to reuse an instance of FTPSClient or must a new
>  > >  > FTPSClient instance be created on every reconnect?
>  > >  >
>  > >  > /Bengt
>  > >  >
>  > >  >
>  > >
>  >
>
> > ---------------------------------------------------------------------
>  > To unsubscribe, e-mail: [hidden email]
>  > For additional commands, e-mail: [hidden email]
>  >
>  >
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]