Some questions about start a new stream in libp2p host - libp2p

First question is: When a host try to start a new stream to a remote with some streamhandler in libp2p, it seems the remote peer would automatically start a goroutine to handle this stream, while the local peer need to manually start this handler. What is the purpose of such design?
Second question is: If some remote peer start a new stream or connect my local host, can I monitor the inbound stream or get the inbound stream. Something like net.Listener.Accept().If so which method should I use.
Thank you.

Related

How to use a existing established TCP connection?

I wanted to use a already established TCP connection to send request and receive response
tcp4 0 0 192.168.58.72.50913 17.248.162.6.https ESTABLISHED
as you can see above, a tcp connection is already in established state, this connection is created by some other process. I being a root user wanted to use the same connection to send request and receive response. is this possible. ??? if yes, can you please tell how to do it ?
If you mean to SHARE the connection (or FD, file descriptor) between the existing process -- that's quite dirty and not recommended.
Although there's a way to pass FD between processes (see this: Can I share a file descriptor to another process on linux or are they local to the process?), it needs target process to send its FD to you (rather than fetch the FD by yourself).

connect on "connection less" boost::asio::ip::udp::socket

I've been learning about UDP socket lately by browsing the net and all the pages that were explaining it were mentioning that UDP sockets are "connection less". This, if I understand it correctly means that one does not have a "connection" between two sockets but instead shoots datagram packets to specified endpoints without knowing whether the other end is listening.
Then I go and start reading the boost::asio::ip::udp::socket docs and find that it mentions API like:
async_connect: Start an asynchronous connect.
async_receive: Start an asynchronous receive on a connected socket.
async_send: Start an asynchronous send on a connected socket.
Now this is a bit confusing for a novice. I can find 3 possible causes for my confusion (in order of likehood :) )
I'm missing something
The asio implementation is doing something behind the scenes to virtualize the connection.
The documentation is wrong
There is also a slight glitch in the docs, when you open the page for basic_datagram_socket::async_connect the example in there is instantiating TCP sockets (instead of UDP ones).
Would someone please enlighten me?
The Single UNIX specification has a better explanation of what connect does for connection-less sockets:
If the initiating socket is not connection-mode, then connect() sets the socket's peer address, but no connection is made. For SOCK_DGRAM sockets, the peer address identifies where all datagrams are sent on subsequent send() calls, and limits the remote sender for subsequent recv() calls.

JSch session.connect() hungs with CoreFTP

I have CoreFTP configured for localhost and the next code:
JSch.setLogger(new MyJschLogger()); //class for console output
Session session = jsch.getSession("user", "localhost", 21);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword("password");
session.connect();
when program achieves connect(), two messages appear at console output:
INFO: Connecting to localhost port 21
INFO: Connection established
...and nothing more happens. After some minutes, connection is closed by foreign host exception appears.
Why?
Thanks for all!
Port 21 is the normal port for FTP. JSch is only an SSH client, with support for SFTP in the ChannelSFTP class. JSch knows nothing about FTP (and SFTP is unrelated to FTP, other than by name and that it allows similar things).
You need to setup your server to use the SSH protocol (usually on port 22, but you can use any port, as long as you use the same port on the client). See the documentation - I think you have to check the SSH check box.
Also, if your code is nothing more than what you posted, then nothing more than connecting will happen. To transfer files, you will need to open a ChannelSFTP, and issue the right commands (e.g. call one or more of the put/get methods).
I also faced the similar issue:
"ERROR 2016-04-27 15:05:16,489 [CollectionThreadPool-0] com.dell.supportassist.collector.cli.executor.SSHExecutor: com.jcraft.jsch.JSchException: connection is closed by foreign host"
In my case, channel was getting closed randomly. And when we are trying to re-connect the channel then it was not re-connecting and failing.
This was happening due to looping logic while connecting, so I tried to connect the session without channel by calling method connectWithoutOpenChannel instead of connectinternal(). This resolved my issue.

Resume the same TCP connection

I have a multi-process TCPServer which creates (by fork() on linux) one process (child) per client's request, and in the meanwhile it is listening other connection's request. So I have a 1 to 1 mapping between client and server.
Suppose that one client crashes...is it possible to reconnect it to the same child server process?In other terms..is it possible to restore a pre-exhistent connection which is failed or the attempts to reconnect create a new connection (and then a new child server process)? thank you...
Without some knowledge (by the forker) of the interior session-related details (of the forkee), you have to make assumptions about external details being adequate to determine which remote connections get re-associated with which local connection end-points.
You could change the way things work in your application, though. Oracle SQL*Net does this on some platforms (due to platform limitations).
The initial connection to the TCPServer causes a fork and then opens up a new listening socket, sends back a redirection instruction to connect to the new listening socket & identifying details (to avoid someone else connecting and impersonating the original connector). The client then connects to the new socket, and uses this socket to do any re-connections upon disconnects before their time.
I have done something very similar to this in .NET platform. If you have something which is unique for every connection (for example IMEI of the connecting device this can be done).You should have some global two-dimensional array variable with combination of ProcessID and IMEI. So when device is disconnected and then the device reconnects you only search in this array for this IMEI and you have the process for this device. You should be very carefull with this global variable.
Edited:
I gave an example of some unique identifier. In my case that was the IMEI of the devices. In your case that could be something else which you know it is unique.
I had to do this because I had very big problem with devices breaking up the connection. Every new device was new connection so afterward I ended up with very big CPU usage.
Maybe you can refer https://eternalterminal.dev/howitworks/. Both the client and the server need change.

How do I make a TCP connection between 2 servers if both can start the connection?

I have a defined number of servers that can locally process data in their own way. But after some time I want to synchronize some states that are common on each server. My idea was that establish a TCP connection from each server to the other servers like a mesh network.
My problem is that in what order do I make the connections since there is no "master" server here, so that each server is responsible for creating there own connections to each server.
My idea was that make each server connect and if the server that is getting connected already has a connection to the connecting server, then just drop the connection.
But how do I handle the fact that 2 servers is trying to connect at the same time? Because then I get 2 TCP connections instead of 1.
Any ideas?
You will need to have a handshake protocol when you're connection to a server so you can verify whether it's ok to start sending/receiving data, otherwise you might end up with one of the endpoint connecting and start sending data immediately only to have the other end drop the connection.
For ensuring only one connection is up to a server,you just need something like this pseudocode:
remote_server = accept_connection()
lock mutex;
if(already_connected(remote_server)) {
drop_connection(remote_server)
}
unlock mutex;
If your server isn't multithreaded you don't need any locks to guard you when you check whether you're already connected - as there won't be any "at the same time" issues.
You will also need to have a retry mechanism to connect to a server based on a small random grace period in the event the remote server closed the connection you just set up.
If the connection got closed, you wait a little while, check if you're already connected (maybe the other end set up a connection to you in the mean time) and try to connect again. This is to avoid the situation where both ends set up the connection at the same time but the other end closes it because of the above logic.
Just as an idea. Each server accept a connection, then find out that it has got two TCP connections between the same servers. Then one connection is chosen to be closed. The way to choose what connection to close you just need to implement. For example both servers should compare their names ( or their IP address or their UID) and connection initiated by the server whose name is less (or UID) should be closed.
While better solution implies making a separate "LoadBalancer" to which all your servers are connected here is the small suggestion to make sure that connections are not created simultaneously.
Your servers can start connections in different times by using
bool CreateConnection = (time() % i == 0)
if (CreateConnection){ ... }
where i is the ID of the particular server.
and time() could be in seconds or fractions of a second, depending on your requerements.
This will guarantee that you never get two servers connecting at the same time to each other. If you do not have IDs for servers, you can use a random value.

Resources