Is it possible to use gRPC such that all calls between two remote hosts
use a TCP connection that is established outside of gRPC? I would also like
to determine whether this TCP connection can be multiplexed for more than
one gRPC call, that the calls may be in either directions, and that gRPC
not close the socket.
The intent is to be able to use gRPC when two ends of gRPC are across a
firewall. The firewall only allows establishing a single TCP connection
that is initiated from within the firewall.
For the requirements only C++ and Java implementations may be on either side.
Maybe. The main problem will probably be that you don't want gRPC to close the socket; it's unclear when you want gRPC to release the socket back to you. It's also unclear whether you need this on server-side or client-side.
gRPC uses HTTP/2 which can naturally multiplex multiple bi-directional calls over a single TCP connection. C++ also allows you to provide it an existing fd. Java doesn't support passing an fd out-of-the-box, but it should be possible using the JNI Netty EpollSocketChannel. I would only expect those to work on client-side today, though.
This may be something that deserves a GitHub issue as a feature request.
Related
Let's say I am creating a chat (client-server) application intended to use in my local network. I'm thinking about having a server which communicates with clients and multiple clients which communicate only with the server.
My initial thought was that the server is going to have TCP socket listener as well as each client. The problem arises when I have both the server side application and client side application on the same machine listening to the same port. This is not allowed. The same problem arises with two client side applications running on my computer which cannot both listen to the same TCP port.
How can I solve this problem? What is the common strategy?
The problem only exists if the client apps are binding to a specific port that the server app and/or other client apps are also binding to, instead of binding to ephemeral ports (which is the usual case for clients to do).
To bind to an ephemeral port, either don't bind at all (connect() does an implicit bind), or else bind to port 0 and let the OS pick an available port. In most cases, servers should bind to specific ports and clients should bind to ephemeral ports, when possible.
Your client apps do not need their own listening sockets to communicate with the server. They would need that only if they are performing things like peer-to-peer data transfers, etc. And even then, they should be using ephermeral ports, or pre-configured ports (in cases of firewalls, NATs, etc), and can use the server-based communications to share what those ports are with each other while negotiating the transfers.
I have been going through this websockets article.
Can a web-socket communicate with a TCP/UDP Socket and viceversa?
Websockets use TCP sockets.
Websockets are a higher level technology relying on TCP sockets, exactly the same way HTTP is transported over TCP sockets.
In fact, Websockets are a special extension of HTTP. The client issues a special HTTP request that leaves the underlying TCP socket open, which then allows both the client and the server to push data on the connection.
What you essentially need is a WebSockets client library in your application. This will utilise TCP sockets on a lower level, and talk to your webserver using the WebSockets protocol.
The benefit of this approach is that your application code only has to deal with the library's higher-level API as well, instead of the nitty-gritty sockets API, where you'll have to implement HTTP and/or WebSockets again.
I'm trying to implement an HTTP proxy for learning and debug purpose.
The support of plain HTTP transactions was pretty straightforward to implement and now I'm looking to implement support for SSL/TLS tunnels.
From RFC 7230:
A "tunnel" acts as a blind relay between two connections without
changing the messages. Once active, a tunnel is not considered a party
to the HTTP communication, though the tunnel might have been initiated
by an HTTP request.
It's not very clear whether I shall build the TLS socket from the socket on which the HTTP CONNECT transaction took place. I assume it is the case, since HTTP is stateless, but I just want to be sure.
When a client connects to an HTTP proxy, CONNECT is used to have the proxy establish a persistent TCP connection with the target TCP server. Then the proxy blindly passes data as-is back and forth between the two TCP connections until either the client or server disconnects, then the proxy disconnects the other party. This allows the client to send data to the server and vice versa, such as TLS packets. This is important so the TLS server can verify the client's identity during the TLS handshake.
So, to answer your question - yes, the client must establish a TLS session with the target server using the same TCP socket that it used to issue the CONNECT request on. Once the CONNECT request has succeeded, the client can treat the existing TCP connection as if it had connected to the server directly. The proxy is transparent at that point, neither party needs to care that it is present.
As far as I can see there is no way to run Akka remote tcp client placed behind a firewall, because every Akka peer has to have a tcp server socket to be able to receive messages. Am I right?
I need to create a pure tcp client with Akka that would be able to connect to a remote server and receive responses from it but unable to receive incoming connections.
Yes you are. All akka nodes should be able to receive incoming requests.
Typically response is posted into a akka queue.
I doubt if it can happen without an incoming connection.
I guess you need to go through a proxy server.
In order to do that you need to pass the httpProxy and httpPort flag to the JVM.
You can do that with "-J" switch or passing in the JAVA_OPTS environment variable
I´ve searched and didnt find which ports does XMPP uses.
I need to implement XMPP server and client and use XML transfer, file transfer and streaming.
Do they use different ports?? Is there a way I can make them use all the same, so I dont need to bother the network admin?
Thanks
According to Wikipedia:
5222 TCP XMPP client connection (RFC 6120) Official
5223 TCP XMPP client connection over SSL Unofficial
5269 TCP XMPP server connection (RFC 6120) Official
5298 TCP UDP XMPP JEP-0174: Link-Local Messaging / Official
XEP-0174: Serverless Messaging
8010 TCP XMPP File transfers Unofficial
The port numbers are defined in RFC 6120 § 14.7.
According to Extensible Messaging and Presence Protocol (Wikipedia), the standard TCP port for the server is 5222.
The client would presumably use the same ports as the messaging protocol, but can also use http (port 80) and https (port 443) for message delivery. These have the advantage of working for users behind firewalls, so your network admin should not need to get involved.
The ports required will be different for your XMPP Server and any XMPP Clients. Most "modern" XMPP Servers follow the defined IANA Ports for Server-to-Server 5269 and for Client-to-Server 5222. Any additional ports depends on what features you enable on the Server, i.e. if you offer BOSH then you may need to open port 80.
File Transfer is highly dependent on both the Clients you use and the Server as to what port it will use, but most of them also negotiate the connect via your existing XMPP Client-to-Server link so the required port opening will be client side (or proxied via port 80.)
The official ports (TCP:5222 and TCP:5269) are listed in RFC 6120. Contrary to the claims of a previous answer, XEP-0174 does not specify a port. Thus TCP:5298 might be customary for Link-Local XMPP, but is not official.
You can use other ports than the reserved ones, though: You can make your DNS SRV record point to any machine and port you like.
File transfers (XEP-0234) are these days handled using Jingle (XEP-0166). The same goes for RTP sessions (XEP-0167). They do not specify ports, though, since Jingle negotiates the creation of the data stream between the XMPP clients, but the actual data is then transferred by other means (e.g. RTP) through that stream (i.e. not usually through the XMPP server, even though in-band transfers are possible). Beware that Jingle is comprised of several XEPs, so make sure to have a look at the whole list of XMPP extensions.