I am working on a network proxy project and a newbie to this field. I want to create a tun-tap interface and send an HTTP request through this interface. Here is my approach.
use tun_tap::Iface;
use tun_tap::Mode;
use std::process:Command;
fn cmd(cmd: &str, args: &[&str]) {
let ecode = Command::new(cmd)
.args(args)
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(ecode.success(), "Failed to execte {}", cmd);
}
fn main() {
let iface = Iface::new("tun1",Mode::Tun).unwrap();
cmd("ip", &["addr", "add", "dev", 'tun1', '192.168.0.54/24']);
cmd("ip", &["link", "set", "up", "dev", 'tun1']);
// 192.168.0.53:8000 is my development server created by python3 -m http.server command
let sent = iface.send(b"GET http://192.168.0.53:8000/foo?bar=898 HTTP/1.1").unwrap();
}
But my development server is not receiving any request. And not displaying any error.
A TUN interface sends and receives IP packets. This means that the data you give to iface.send must be an IP packet in order to be delivered. You can see in your code you're not indicating what server you are connecting to because at this layer connections "don't even exist". The IP in the HTTP request happens to be there because HTTP protocol says so, but you must already be connected to the server when you send this information.
In order to send and receive data from a tun interface you'll have to build an IP packet.
Once you can send and receive IP packets, you'll have to implement the TCP protocol on top of that to be able to open a connection to an HTTP server. On this layer (TCP) is where the concept of "connection" appears.
Once you can open and send/receive data over a TCP connection, you'll have to implement the HTTP protocol to be able to talk to the HTTP server, i.e. "GET http://192.168.0.53:8000/foo?bar=898 HTTP/1.1".
Related
In the documentation for HTTP.jl, the HTTP.serve function has an optional keyword argument tcpisvalid::Function (::TCPSocket) -> Bool which says it can be used to
check accepted connection before processing requests. e.g. to implement source IP filtering, rate-limiting, etc.
How can I get the client IP address from a TCPSocket object?
You can use the function Sockets.getpeername. According to the Sockets docs, the function signature is:
getpeername(sock::TCPSocket) -> (IPAddr, UInt16)
And the description is:
Get the IP address and port of the remote endpoint that the given socket is connected to. Valid only for connected TCP sockets.
So, for example, if you run your simple server with the following code...
HTTP.serve(app, "127.0.0.1", 8081; tcpisvalid=sock -> begin
host, port = Sockets.getpeername(sock)
println("Request from... $host:$port")
true
end)
and then in a separate terminal run...
$ curl http://localhost:8081/
the output from your Julia server will be...
Request from... 127.0.0.1:40958
I know there are a lot of different comminucation protocals like: http, tcp, ssh, socks5, SMTP, POP,etc.
I also know that to achieve a comminication, we need to connect localhost:localport to remotehost:remoteport. For example, if we google something, we would connect a random local port to www.google.com: 80. If we ssh a remote host, we would connect a random local port to remotehost: 22.
My question is: Are communication protocol Half-duplex or Full-duplex?
I guess the answer is Half-duplex. Because I think in http connection, at first we send the request from localhost:localport to remotehost:80, and then the remote server send its response from remotehost:80 to localhost:localport. Similarly, in ssh connection, at first we sent the ssh commands to remote host, after receiving the commands, the remote host do something and send the results back to the local host.
So I think in one connection between localhost:localport and remotehost:remoteport, the message is sent either from localhost:localport to remotehost:remoteport, or from remotehost:remoteport to localhost:localport.
Am I right?
As explained in this article:
SSH is a bidirectional full duplex protocol, which means that it’s not synchronous like HTTP where you need to send a message for a response to happen.
With SSH the remote host might want to tell you something even if you have remained silent. This connector uses a callback flow approach to decouple the “sending” operation from the “receiving” operation.
As documented in this IETF draft, most implementations do allow full-duplex HTTP (for 2xx responses).
Full-duplex HTTP follows the basic HTTP request-response semantics but also allows the server to send response body to the client at the same time when the client is transmitting request body to the server.
Requirements for full-duplex HTTP are under-specified in the existing HTTP (Hypertext Transfer Protocol -- HTTP/1.1) specification, and this memo intends to clarify the requirements of full-duplex HTTP on top of the basic HTTP protocol semantics.
My understanding regarding network model communication:
Application layer:
1. HTTP(Not Persistent or stateless): For exchanging messages like get, post, put etc. Here connection is made to webserver and disconnected after sending response. So server will not keep track of the previous requests.
2. Websockets(Persistent or statefull): For creating a communication channel that will be open to exchange data. Here we can keep track of the previous requests. Like we can know how many users are currently connected to our server.
Transport layer:
TCP(Persistant and Statefull): Will let the server know to which application to connect using port number. Both HTTP and web sockets will work upon this layer.
Considering working with HTTP and TCP:
I make a HTTP request from browser(application layer):
Connects to web server sends all files requested and also makes a TCP connection with the application(transport layer).
After sending response it's disconnected.
My confusion:
I got totally confused when I heard, read that TCP is Statefull and Persistant connection.
Q1. Now after step three is browser still connected to webserver because of TCP?
Q2. Is the context object we get in server side in c# code is the complete request packet with HTTP info, TCP info, function to invoke or controller to invoke in MVC etc?
Q3. If client and server are still connected with TCP. Then on next HTTP request does it will use the available TCP connection or will create new TCP and HTTP connection? Why can't it use previous TCP to communicate? Or TCP will be destroyed after HTTP? Or what's happening?
I have a mirth channel that listens to a source and then deploys the inbound communications to several channels. One of these channels sends the HL7 to an application I am developing, and I do not know where to send my ack message. Should I send it to the inbound port of the original message, or does MIRTH have a specific process for sending acknowledgements?
Acknowledgements in Mirth are handled in destination's Response Transformer. To get there, go to the Destinations tab, select your destination if there are more than one, under Channel Tasks menu on the left side select Edit Response. The msg variable there is your response message. To generate an acknowledgement use Postprocessor script or place your acknowledgement into responseMap directly and configure the Response setting of the Source connector.
I am working on a sip client - asterisk server. I am using tcp connections.
The client side is Zoiper as for a first test.
Registration and outbound calls do work as expected, but after 3-4 minutes from registration process or an outgoing call, when testing incoming calls I do get this message on the server:
tcptls.c:446 ast_tcptls_client_start: Unable to connect SIP socket to ip:port: Connection timed out
The invite message (incoming call) never gets on the client (Zoiper softphone).
Why is this error showing up?
The reason why this appears from my assumption is because of the fact that neither the client or the server are sending keep alive messages, so after a tcp socket timeout the client which is behind a nat will not be reachable from the server side anymore.
This error come because your NAT (or 3g if you use 3g) drop connection. As result there are no way use same connection anymore.
Correct behavour of you app - send SIP OPTIONS message, if timeout - do registration again.
And yes, you need send keepalives(recomended method - OPTIONS message) or setup keepalive on asterisk side and setup in your side correct answer.