How to get the remote host from a rsocket - rsocket

I now receive an rsocket connection in my spring project, and then I want to get its remote address and port, how should I get it?Similar to using socket.getRemoteSocketAddress() to get the remote address of the socket.
#ConnectMapping
public void connectMapping(RSocketRequester requester) {
// there is a resockt connect, how can i get the remote host from it
RSocket rSocket = requester.rsocket();
// TODO
logger.info("host port");
}

Unfortunately, I think even if you grab the RSocketRequester in #ConnectMapping or #MessageMapping method it is an internal detail. io.rsocket.core.RSocketRequester via RequesterResponderSupport holds the DuplexConnection which represents a connection over tcp, web socket or in-process. It is not exposed via a public API.
This is a worthy request but you will need to file a feature request to get this added unless I'm missing something obvious.
It isn't clear that there is a hook in https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/api/org/springframework/boot/rsocket/server/RSocketServerCustomizer.html to let you see the DuplexConnection (tcp or web socket etc) as it's established.

Related

Does `select` handles multiple endpoints or multiple sockets?

I am new to network programming, and I have some confusion with select function.
For a server program, we need to first create a fd to socket endpoint (server's ip and port without client's ip and port) with socket, bind and listen, then if there is a TCP connection to this socket endpoint, then accept returns the fd to the socket (server's ip, port and client's ip, port). Then we use recv on this socket's fd, and if there is no data to receive, the recv will block (for blocking socket).
I learned that select is used to handle non-blocking multiple connections. But which connection level does it handles? Does it handles multiple socket endpoints, or handles multiple sockets of one single socket endpoint?
For a normal server program, I think the socket endpoint is always single, and there are maybe hundreds of sockets connected to this endpoint. So I think handling multiple socket endpoints may be less useful to handling multiple sockets. But when talking about IO multiplexing, I find that many articles seems talking about handling multiple socket endpoints. While for handling multiple sockets to a single socket, I can't find a way to get all sockets, and put them to select's set of fds, since accept only accepts one sockets a time.
"Does it handles multiple socket endpoints or handles multiple sockets of one single socket endpoint?" -- There is no such thing as multiple sockets of a single socket endpoint. Every socket is an endpoint to the network communication. It just happens that the piece of code which deals with that socket might be different from the others. Consider the following socket descriptors:
int sock_acpt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
listen(sock_acpt, 5);
int sock_cli = accept(sock_apt, ....);
Both the socket descriptors sock_acpt and sock_cli are the endpoints of different communications. After setting sock_acpt in passive mode by calling listen(), the socket just listens for TCP connection, and the server's TCP stack will manage any data that appears on that socket (most probably TCP Handshakes). While sock_cli is the end of an already established connection, and in general, the data on that socket is managed by the user-level application.
Now coming to select(), it is an IO Multiplexer, not a Network IO multiplexer. So any descriptor which can be viewed as an IO endpoint can be used with the select(). Referring to our socket descriptors sock_acpt and sock_cli, both are IO endpoints of different communications, so you can use both of them with select(). You generally do something like below
for ( ; ; ) {
fd_set rd_set;
FD_ZERO(&rd_set);
FD_SET(sock_acpt, &rd_set);
FD_SET(sock_cli, &rd_set);
if (select(sock_acpt > sock_cli ? sock_acpt + 1 : sock_cli + 1, \
&rd_set, NULL, NULL, NULL) <= 0) {
continue;
}
if (FD_ISSET(sock_acpt, &rd_set)) {
// Accept new connection
// accept(sock_acpt, ...);
}
if (FD_ISSET(sock_cli, &rd_set)) {
// Read from the socket
// read(sock_cli, ...);
}
}
But using select() is not limited to sockets, you can use with the file IO (fileno(stdin)), with the signal IO (signalfd()) and any other which can be viewed as IO endpoint.

Jenkins JNLP port exposes internal ip

We have configured our Jenkins server to use a fixed port and JNLP 4.
Our info sec team has flagged that if one were to open a web browser pointing at the JNLP port, the internal properties below are listed which includes the internal ip of the Jenkins server.
Jenkins-Agent-Protocols:
Jenkins-Version:
Jenkins-Session:
Client:
Server:
Remoting-Minimum-Version:
Is this information necessary? Is this something which can be suppressed?
From the source: https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/TcpSlaveAgentListener.java
It looks like there is no mechanism to turn it off, and according to the comments, it seems to be only for testing:
String header = new String(head, Charsets.US_ASCII);
if (header.startsWith("GET ")) {
// this looks like an HTTP client
respondHello(header,s);
return;
}
// otherwise assume this is AgentProtocol and start from the beginning
(...)
/**
* Respond to HTTP request with simple diagnostics.
* Primarily used to test the low-level connectivity.
*/
private void respondHello(String header, Socket s) throws IOException {
(...)
If infosec requires you to turn this off, you might need to open a support ticket with cloudbees.

StarScream websocketDidReceivePong is not getting called for writePing

I would like to send periodic pings to server to keep the connection alive.
This is the function to send ping
socket.writePing(NSData())
But I am not getting the pong back
func websocketDidReceivePong(socket: WebSocket){
wsConsole.text = wsConsole.text .stringByAppendingString("\n websocket received pong")
}
the above delegate will get fired when server sends back the pong.
FYI:
I am able to successfully establish web socket connect send message and close connection and I have implemented and I have given socket.delegate=self
WebSocketPongDelegate
Here is the web socket url that I am using for testing purposes
ws://echo.websocket.org/
I am wondering why I am not getting the pong back from web socket server.
Is your socket a property of your class to make sure it sticks around? If you allocate it just on a function stack it will fall out of scope and the delegates will never get called. Also the pongDelegate is separate from the regular delegate, so you need to set that to self as well:
socket.pongDelegate = self

mina server response port different from port incoming messages

I set up a server that receives messages over port xxx, but I want to respond to port yyy.
Is there a simple way to achieve this?
My server:
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.setHandler(new MessageHandler());
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new protocolCodecFilter(codecFactory));
acceptor.getSessionConfig().setReadBufferSize(bufferSize);
acceptor.bind(new InetSocketAddress(port));
The encode method of my encoder:
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
byte[] writeBytes = (byte[]) message;
IoBuffer buffer = IoBuffer.allocate(writeBytes.length).setAutoExpand(false);
buffer.put(writeBytes);
buffer.flip();
out.write(buffer);
writeMessage(session,writeBytes);
}
The msessage should be written to a different port. How do I achieve this?
If you want to response message using different tcp port, you must make another other tcp connection first, which means you have two servers and tow clients.
request
client1---------->server1
reponse
server2---------->client2

How to check server connection

i want to check my server connection to know if its available or not to inform the user..
so how to send a pkg or msg to the server (it's not SQL server; it's a server contains some serviecs) ...
thnx in adcvance ..
With all the possibilities for firewalls blocking ICMP packets or specific ports, the only way to guarantee that a service is running is to do something that uses that service.
For instance, if it were a JDBC server, you could execute a non-destructive SQL query, such as select * from sysibm.sysdummy1 for DB2. If it's a HTTP server, you could create a GET packet for index.htm.
If you actually have control over the service, it's a simple matter to create a special sub-service to handle these requests (such as you send through a CHECK packet and get back an OKAY response).
That way, you avoid all the possible firewall issues and the test is a true end-to-end one. PINGs and traceroutes will be able to tell if you can get to the machine (firewalls permitting) but they won't tell you if your service is functioning.
Take this from someone who's had to battle the network gods in a corporate environment where machines are locked up as tight as the proverbial fishes ...
If you can open a port but don't want to use ping (i dont know why but hey) you could use something like this:
import socket
host = ''
port = 55555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)
while 1:
try:
clientsock, clientaddr = s.accept()
clientsock.sendall('alive')
clientsock.close()
except:
pass
which is nothing more then a simple python socket server listening on 55555 and returning alive

Resources