0 votes
by (600 points)

I am connecting to CB SFTP using rebex dll in c#. I am getting he below exceptions intermittently in between during upload/download of files as below

Message: Error while connecting SFTP: No connection could be made because the target machine actively refused it.
at Rebex.Net.Sftp.bxywe(String p0, Int32 p1, SshParameters p2, lrvux p3)
at Rebex.Net.Sftp.jlehg(String p0, Int32 p1, SshParameters p2)

at NeSTBLL.BLL_SFTPEngine.ConnectSftp(Sftp& objSFTP)


Timestamp: 5/13/2024 1:07:40 PM
Message: Error while connecting SFTP: Connection attempt timed out.
at Rebex.Net.Sftp.bxywe(String p0, Int32 p1, SshParameters p2, lrvux p3)
at Rebex.Net.Sftp.jlehg(String p0, Int32 p1, SshParameters p2)
at NeSTBLL.BLL_SFTPEngine.ConnectSftp(Sftp& objSFTP)

I am connecting to CB SFTP as below. If i specify key exchange algorithm in the server code level will this issue be resolved.
objSFTP.Connect(sSFTPHost[0], int.Parse(sSFTPHost[1]));
objSFTP.Login(sSFTPHost[2], sSFTPHost[3]);

Applies to: Rebex SFTP

2 Answers

0 votes
by (148k points)

This error indicates that the SFTP client was unable to establish a TCP connection to the server. Specifying a different SSH key exchange algorithm won't resolve this (it has nothing to do with TCP).

To resolve the issue, make sure that network connectivity is working on the client machine, that the SFTP server is up and running, and that connections to the SFTP server from the client machine are not blocked by firewalls or routers along the way.

To make sure the issue is not in Rebex SFTP library, try connecting to the server using the .NET API, as described in this answer.

by (600 points)
How can we prove the issue is due to TCP connectivity issue. Both client and server side are mentioning that there is no network or firewall issue . Customer is blaming it is an issue  with Rebex library or the connectivity code . Actually we upgraded Rebex dll 6.0.8372  suited for application framework (using 3,5)

Kindly revert asap
by (148k points)
To prove this, use a network protocol analyzer such as [Wireshark](https://www.wireshark.org/) to capture a communication log at TCP level. This way, it is possible to determine which side of the connection is to blame.
by (600 points)
using System.Net;
using System.Net.Sockets;
using System.Linq;

var entry = Dns.GetHostEntry(sSFTPHost[0]);
var address = entry.AddressList.Where(address => address.AddressFamily == AddressFamily.InterNetwork).First();
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(address, int.Parse(sSFTPHost[1]));

In the above code we are simply connecting using SFTP host and port. There is no rebex library referred here. So how can we confirm issue is not with rebex package. Also the connectivity timed out or target machine refused exception is happening in between only
by (148k points)
Yes, there is no Rebex library referenced here. Therefore, if the code still fails with the same error, it would strongly suggest that the issue is not in Rebex library, but elsewhere. Of course, if that degree of certainty is not sufficient for you, a network protocol analyzer such as Wireshark is the way to go.
by (600 points)
using System.Net;
using System.Net.Sockets;
using System.Linq;

var entry = Dns.GetHostEntry(sSFTPHost[0]);
var address = entry.AddressList.Where(address => address.AddressFamily == AddressFamily.InterNetwork).First();
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(address, int.Parse(sSFTPHost[1]));

I was able to connect to the SFTP Host and port using the above code.
My application is set in a windows service in a windows 2016 server. Connection is failing in between. At times it is fine. .Few applications with same Rebex dll  and connectivity code are set in another server but it is set in the same network. Those applicators are not having any such  connectivity issues.

Connectivity Code
IsActive = objSFTP.GetConnectionState();

                if (IsActive.Connected == false)
                {
                    objSFTP.Connect(sSFTPHost[0], int.Parse(sSFTPHost[1]));
                    objSFTP.Login(sSFTPHost[2], sSFTPHost[3]);
                }
by (148k points)
Well, if you assume this is a Rebex issue, you can try replacing Rebex SFTP's transport layer with custom code to rule this out:
https://forum.rebex.net/22824/how-resolve-sftp-connectivity-issue-happening-using-rebex?show=22839#a22839
0 votes
by (148k points)
edited by

If you assume that Rebex SFTP connection-establishing code might be blame for this issue, you can try bypassing it and use your own transport layer instead. To do so, implement a custom ISocketFactory (let's call it MySocketFactory) and instruct the Sftp instance to use it:

// call this before the Connect method:
objSFTP.SetSocketFactory(MySocketFactory.Instance);

objSFTP.Connect(sSFTPHost[0], int.Parse(sSFTPHost[1]));
objSFTP.Login(sSFTPHost[2], sSFTPHost[3]);

Use the following MySocketFactory class with this code:

public class MySocketFactory : ISocketFactory
{
    public static ISocketFactory Instance
    {
        get { return _instance; }
    }

    private static readonly ISocketFactory _instance = new MySocketFactory();

    private MySocketFactory()
    {
    }

    ISocket ISocketFactory.CreateSocket()
    {
        return new MySocket();
    }

    private class MySocket : ISocket
    {
        private Socket _socket;
        private int _timeout;

        public MySocket()
        {
        }

        public int Timeout
        {
            get
            {
                return _timeout;
            }
            set
            {
                _timeout = value;
                var socket = _socket;
                if (socket != null)
                {
                    socket.SendTimeout = _timeout;
                    socket.ReceiveTimeout = _timeout;
                }
            }
        }

        public bool Connected
        {
            get { return _socket.Connected; }
        }

        public EndPoint LocalEndPoint
        {
            get { return _socket.LocalEndPoint; }
        }

        public EndPoint RemoteEndPoint
        {
            get { return _socket.RemoteEndPoint; }
        }

        public void Connect(EndPoint remoteEP)
        {
            var socket = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(remoteEP);

            socket.NoDelay = true;
            socket.SendTimeout = _timeout;
            socket.ReceiveTimeout = _timeout;
            _socket = socket;
        }

        public void Connect(string serverName, int serverPort)
        {
            var entry = Dns.GetHostEntry(serverName);
            var address = entry.AddressList.Where(a => a.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();
            address = address ?? entry.AddressList.Where(a => a.AddressFamily == AddressFamily.InterNetworkV6).FirstOrDefault();
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(address, serverPort);

            socket.NoDelay = true;
            socket.SendTimeout = _timeout;
            socket.ReceiveTimeout = _timeout;
            _socket = socket;
        }

        public bool Poll(int microSeconds, SocketSelectMode mode)
        {
            return _socket.Poll(microSeconds, (SelectMode)mode);
        }

        public int Receive(byte[] buffer, int offset, int count, SocketFlags socketFlags)
        {
            return _socket.Receive(buffer, offset, count, socketFlags);
        }

        public int Send(byte[] buffer, int offset, int count, SocketFlags socketFlags)
        {
            return _socket.Send(buffer, offset, count, socketFlags);
        }

        public void Shutdown(SocketShutdown how)
        {
            _socket.Shutdown(how);
        }

        public void Close()
        {
            _socket.Close();
        }
    }
}

Now, Rebex SFTP will use the class for all its communication. If "No connection could be made because the target machine actively refused it" errors still appear, you will be able to determine whether they are coming from our library or from MySocketFactory class (or rather from the underlying .NET's System.Net.Sockets.Socket class).

by (600 points)
Plese share the class  ISocketFactory and how to get Isocket
by (148k points)
ISocketFactory and ISocket interfaces are declared in Rebex.Net namespace by Rebex.Networking.dll assembly, which comes with Rebex SFTP: https://www.rebex.net/doc/api/Rebex.Net.ISocketFactory.html

To use them, add the MySocketFactory class above to your application. Required "usings":

using System;
using System.Net;
using System.Net.Sockets;
using System.Linq;
using Rebex.Net;
by (600 points)
edited by
With the above socket connection code we may be able to say it is rebex library related or not. But Is there any option to prove  the connectivity issue is due to network issue or any other exactly
 . Cannot use wireshark  or any other tool to check the same since it is in banking environment. Can we enable any log code level to trace the connectivity failure issue happening in between. Please note files are uploaded or downloaded to SFTP server via windows service and the connectivity is  failing in between. It is not happening every time.
We need to prove the exact issue code level if possible. We are using the upgraded version of rebex dll suited to the .net  framework  version 3.5 for connecting  as part of the SFTP upgrade ar server .
      From the server side it is updated there is no exception logs ar their end as such and hence we are stuck. We need to prove the exact root cause as soon as possible.
by (148k points)
You can easily add logging capabilities to the custom MySocketFactory class based on your requirements. You can also enable logging in Rebex SFTP: https://www.rebex.net/kb/logging/
However, since what you are dealing with is apparently a TCP connectivity issue, these logs are most likely to only confirm what is already known - that the attempt to establish a TCP connection to the server occasionally fails.
To be able to resolve this in a restricted environment, I'm afraid the operators of that machine will have to get in touch with someone who is familiar with TCP/IP and can look into the networking issue. I'm sure most banking institutions have some technical staff who can look into what's going on in their protected networks.
by (600 points)
My query is can i enable rebex communication logging to track the connection issues. Also where i can place the code in the existing  connectivity/upload  code
connectivity code
 private void ConnectSftp(ref Sftp objSFTP)
        {
            try
            {
                Common.WriteLogService("ConnectSftp()-Process Started", "", false);
                SftpConnectionState IsActive = null;
                string[] sSFTPHost = ConfigurationSettings.AppSettings["SFTPHost"].Split('|');
                string Active = string.Empty;
                if (objSFTP == null)
                {
                    objSFTP = new Sftp();
                }

              
                //--------------------------------------------------



                // IsActive = objSFTP.GetConnectionState();    //--- commented by mathew for SFTP Rebex connectivity issue on 20240516 -

                //if (IsActive == null || IsActive.Connected == false)
                //{
                    Common.WriteLogService("ConnectSftp()-SFTP Connectivity Process via Socket Started", "", false);
                    objSFTP.SetSocketFactory(MySocketFactory.Instance);
                    objSFTP.Connect(sSFTPHost[0], int.Parse(sSFTPHost[1]));
                    objSFTP.Login(sSFTPHost[2], sSFTPHost[3]);
                    Common.WriteLogService("ConnectSftp()-Successfully via Socket connected with SFTP Host", "", false);
                //}
                try
                {
                    SetSFTPStatus("C", 2);
                }
                catch { }
                Common.WriteLogService("ConnectSftp()-Process Completed", "", false);
            }
            catch (Exception ex)
            {
                //--- try catch block added on 20240516
                try
                {
                    objSFTP.Disconnect();
                    Common.WriteLogService("ConnectSftp()-SFTP connection disconnected", "", false);
                }
                catch (Exception ex1)
                {
                    Common.WriteLogService("ConnectSftp()-Error while disconnecting to SFTP: Exception:" + ex1.Message
                     + ",Inner Exception:" + ex1.InnerException + ",Stack Trace:" + ex1.StackTrace, "", true);
                }
                objSFTP = null; // added on 20240516
                Common.WriteLogService("ConnectSftp()-Error while calling ConnectSftp(): Exception:" + ex.Message
                    + ",Inner Exception:" + ex.InnerException + ",Stack Trace:" + ex.StackTrace, "", true);
                try
                {
                    SetSFTPStatus("E", 2);
                }
                catch { }
            }
        }
       
        upload code
         public void Upload()
        {
            try
            {
                variableIsUploadLiveSetTime = DateTime.Now;

                objSFTPBLL = new DAL_SFTPEngine();

                DataSet dsUploadFileList = objSFTPBLL.GetFTPFileDetails("U");
                if (dsUploadFileList.Tables[0].Rows.Count > 0)
                {
                    string FileList = "File Uploads" + Environment.NewLine;

                    foreach (DataRow drU in dsUploadFileList.Tables[0].Rows)
                    {
                        string strFTPUploadId = drU["SFTPFileId"].ToString();
                        string strFileType = drU["FileType"].ToString();
                        string strFileName = drU["FileName"].ToString();
                        string strMode = drU["Mode"].ToString();
                        string strStatus = drU["Status"].ToString();

                        FileList += strFileName;
                        if (SFTP_Upload_Rebex(strFTPUploadId, strFileType, strFileName, strMode, strStatus))
                        {
                            FileList += strFileName + " Upload Succeeded" + Environment.NewLine;

                            objSFTPBLL.UpdateFTPFileUploadQueueDtls(strFTPUploadId, "C");
                            string source = GetFilePath("FP") + "" + strFileName;
                            string destination = GetFilePath("FPDONE") + "" + strFileName;

                            File.Move(source, destination);
                        }
                        else
                        {
                            FileList += strFileName + " Uploading Failed " + Environment.NewLine;
                        }
                    }
                    //Common.WriteLogService(FileList,"",false);
                    DisConnectSftp(ref uSftp);
                }
            }
            catch (Exception ex)
            {
                Common.WriteLogService(ex.Message, ex.StackTrace, true);
                SetSFTPStatus("E", 2);
            }
        }
by (600 points)
My query is can i enable rebex communication logging to track the connection issues. Also where i can place the code in the existing  connectivity/upload  code
...