How to use port 80 in a boost::asio server? - c++

I'm using the boost::asio library.
I've been trying to run my server on port 80, but can't get it to do so. Below is the culpable line in my code, with outcomes in the comments:
// This runs fine, and the webpage is visible on localhost:8000
tcp::acceptor a(*io_service, tcp::endpoint(tcp::v4(), 8000));
// This throws an error (at this line)
tcp::acceptor a(*io_service, tcp::endpoint(tcp::v4(), 80));
// This runs fine, but the webpage is NOT visible on localhost or localhost:80
tcp::acceptor a(*io_service, tcp::endpoint());
I've noticed that endpoint only accepts four-digit port numbers. Could this have something to do with it?
How can I see my page running on port 80? Thanks!

I am not sure how it works on Windows, but on Unix, including Linux, ports below 1024 can only be bound by privileged processes. Try running it as root. Of course you should give up the permissions (using setuid system call) after opening the port.

Related

Winsock connect is slow

I have a program that uses Boost.Asio to connect to a server on localhost. Here is the relevant part of the code:
TcpClient::TcpClient(uint16_t port_number) : socket_(service_)
{
boost::asio::ip::tcp::resolver resolver(service_);
boost::asio::ip::tcp::resolver::query resolver_query("localhost", std::to_string(port_number));
auto endpoint_iterator = resolver.resolve(resolver_query);
boost::asio::connect(socket_, endpoint_iterator);
}
The code functions just fine. On Ubuntu, the connect function returns almost immediately. However, on Windows it takes over 2 seconds to complete.
Stepping through the boost code, I found the 2 seconds are spent on the Winsock connect function call.
Am I missing something (either in code, or in the environment) that can speed up this call?
Thank you!
If you have IPv6 enabled then resolver_query("localhost", std::to_string(port_number)); will return an IPv4 and IPv6 address (from experience with the IPv6 listed first). If your server isn't listening on IPv6 then boost::asio::connect will try IPv6 first, wait for it to fail and only then try IPv4.
Either get your server to listen on IPv6, use "127.0.0.1" instead of localhost or restrict the resolver to only return IPv4:
resolver_query(boost::asio::ip::tcp::v4(), "localhost", std::to_string(port_number));

How do I check if a TCP port is already being listened on?

I have a third party library that acts as a HTTP server. I pass it an address and port, which it then uses to listen for incoming connections. This library listens in such a way that it doesn't receive exclusive usage of the port and address it's bound to. As a result, I can listen on the same port multiple times.
I need to run multiple instances of this HTTP server in the same process. Each instance has a default port, but if that port isn't available, it should use the next available port. This is where my problem is; I can end up with two HTTP servers listening on the same port.
I cannot change the HTTP server's code and the HTTP server will not alert me if it cannot listen on the port I give it, so I have to be able to check if a port is already in use before starting each HTTP server. I have tried checking if a port is already being listened on by binding my own socket with SO_REUSEADDR set to FALSE and SO_EXCLUSIVEADDRUSE set to TRUE, but the bind and listen calls both succeed when an existing HTTP server is already listening on that port.
How is this HTTP server achieving this effect, and how can I accurately check if a port is being listened on in this manner?
The quick and dirty method would be to try to connect() to the port on localhost. If the connect() call succeeds, then you know the port is currently being listened on (by whomever received the connection). If the connect call fails (in particular with ECONNREFUSED) then you can be pretty sure that nobody is listening on that port.
Of course, there's a race condition here: Nothing is really stopping another program from swooping in and grabbing the port immediately after you ran the above test, but before you get around to binding to the port yourself. So you should take the result of the test as more of a hint than an absolute rule, and (hopefully) have some way of handling it if you later find out that the port is in use after all.
Use a port number of 0. The OS will pick a free port.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx explains how the different options interact.
You haven't given us nearly enough information to tell us exactly what's going on in your use case, but I can work through one arbitrary use case that would look like what you're seeing.
Let's say you're on Win 2003 or later, and your primary NIC is 10.0.0.1, and everything is running under the same user account.
The first instance of your app comes up, and your test code tries to bind 10.0.0.1:12345 with SO_EXCLUSIVEADDREUSE. Of course this works.
You close the socket, then tell the HTTP server to listen to port 12345. It binds 0.0.0.0:12345 with SO_REUSEADDR, which of course works.
Now a second instance of your app comes up, and your test code tries to bind 10.0.0.1:12345 with SO_EXCLUSIVEADDREUSE. According to the chart in the MSDN article, that works.
You close the socket, then tell the HTTP server to listen to port 12345. It binds 0.0.0.0:12345 with SO_REUSEADDR, which works.
If this is the problem, assuming you can't get the HTTP server to bind a specific address, you can solve things by using 0.0.0.0 in your test code. (Of course if it's one of the other hundreds of possible problems, that solution won't work.)
If you don't know what socket options, address, etc. the HTTP server is using, and don't have the source, just run it in the debugger and breakpoint the relevant calls.

Running client and server on same machine

I have both a client and server application using UDP port 25565.
In order to run these on the same machine, because only one application may bind itself to port 25565, does this mean that it is necessary for me to use two separate ports for transmitting data between the applications?
What I have in mind is the following -
Client -> 25565 -> Server
Client <- 25566 <- Server
Is this the only solution or is there another way of handling this?
Your server application open a port and wait for client to connect.
Client need to know this port in advance so it can establish a connection to the desired service.
Client can use any available ports to initiate this connection (better to use ports > 1000).
The server sees in the incomming packet wich port the client is using, so it will send anwser to it. No need to specify it in your design.
After handshake the TCP/IP connection is then identified by these 4 values : server IP, server port, client IP, client port.
No other connection could have the same four values.
To answer your question. A TCP/IP connection is bi-directional, once established, the server can send data to the client and the other way around.
I would draw the scheme like this :
SERVER port 25565 <-> CLIENT port 25566 (or any other port)
Well, no. Only the server needs to listen on the port 25565 - the client will just connect to that port. There is no reason to specify which client the port should 'use' to connect to that port. Also, once the server has accepted the connection, the port can listen for other requests.
The whole point of separate UDP ports is to eliminate conflicts among applications listening to incoming packets. Changing one of these ports is probably the best solution.
However, if you really want both programs to listen on the same port you will need to use virtual network interfaces such as TUN/TAP (there is a Windows port). Then both applications will bind to the port with tha same number but on the different network interfaces.

How to detect whether a remote computer is running RDP?

How do I detect if a remote client is running Remote Desktop Protocol? and it is also accepting remote desktop connections ??
Like Open an port to detect HTTP and send request, receive request headers and see in request headers information about HTTP so I will know the person is running HTTP weather if he changed the port e.g: running HTTP 6551.
Attempt and make a connection with something that is RDP-connection aware (RDP is not HTTP). Of course, failing to establish an initial handshake is not proof that a connection can not be established. It could be blocked by a firewall, listening on another port, etc.
The MS-RDPBCGR specification, page 16 talks about connecting which in turn defers to X.224, go figure.
It'd likely just be easiest to use Wireshark and observe in-the-wild behavior to develop a minimal detection case. I suspect only the very initial portion of the handshake needs to be generated/replayed in order to "decide" that it's a listening RDP server.
(Or, perhaps use an existing RDP client which has this "test connect" functionality or the ability to be scripted.)
A fast way is to pen a shell and type
telnet IPADDRESS 3389
If you get a connection, chances are good that an RDP server is on the other side. RDP can run on any port, but TCP Port 3389 is set per default.
Windows 7 requires some extra steps to enable the telnet Client.
You could do netstat -a in the command line and see if the default port for remote desktop connection is listening, ie. TCP:3389 but thats only if the client hasn't changed the ports for MSTSC

How boost.asio discover which port is my server app listening on?

it is a little bit strange to me that boost.asio doesn`t use basic concept when client app connecting to the server - using IP address and port. May be I am a little bit noobie in Boost - and I accept that - but anyway I do not understand.
So, I have code like this to get client connected to the server on the localhost:
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while(error && endpoint_iterator != end) {
socket.close();
socket.connect(*endpoint_iterator++, error);
}
Windows in its WinSock 2.0 uses two parameters - IP and port - to identify the server. So, the qurestion is - how exactly Asio finds out which port is server listening to connections on? Does it scans all ports? And, if it does, what will happen if two servers listening on different ports at the same time?
Try,
tcp::resolver::query query("localhost", boost::lexical_cast<string>(port));//assuming port is an int
To answer your question, recall that you are starting the server on port 13. This happens to be the port which runs the Linux daytime service (http://www.sorgonet.com/linux/linuxdaemons/). Hence, they are subsequently able to use query("localhost","daytime") rather than specifying the port.
You are telling it that you want to connect to localhost on the port used by the daytime service. It will look up the appropriate port number in the services file (usually C:\WINDOWS\system32\drivers\etc\services under Windows, I believe /etc/services under Unix). You could also use an explicit port number there.
open netcat listen on port 13 on the localhost
it will accept the demo's connection. type some blabla when it connects and you'll see the output on the demo program
to run the netcat, run:
nc -l -p 13
windows? no netcat? install cygwin, and add netcat