How to get total bytes count transferred over the connection with libcurl? - c++

Libcurl allows to get information how much bytes application level protocol (HTTP, FTP, etc) sent and received. However, is there any way to get amount of bytes that underlying socket sent and received? I am about all data, including, for example, bytes that socket used to establish SSL connection. So, I am basically searching a way to get the same information from libcurl that Apache HTTP client gives in HttpConnectionMetrics.getSentBytesCount() and HttpConnectionMetrics.getReceivedBytesCount().
One idea is to access socket that Libcurl uses directly from C++; however, how to get this socket total sent/received bytes count?

Use CURLOPT_DEBUGFUNCTION and just add up the different parts, as it shows the socket level amounts. This will thus give you an exact number for all protocols speaking plain-text, those not using SSL
However - that won't necessarily give you the counters for the SSL level stuff though in case of HTTPS/FTPS etc, as libcurl doesn't always expose that. It depends on what particular TLS backend it was built to use. The OpenSSL backend should be fine and it will tell you about incoming and outgoing TLS data too (using the same debug callback).

Related

C++ client/server application with single messages and broadcast

I am trying to write a simple client-server application where a client can send or broadcast a message to one or all clients in the network. The server stores all IP addresses that are connected to it, and broadcasts a new IP if a new client connects itself.
I'm not quite sure how to implement the sending of a single message to another client. Would I just have to send a TCP message to the server and put the desired recipient as data in the TCP layer which is then extracted by the server so it knows where to send it?
I also want to add encryption to the messages which would then no longer allow the server to read the data, so I'm not sure how to solve that!?
I am using c++ and Qt5 for the implementation
I'm not quite sure how to implement the sending of a single message to
another client. Would I just have to send a TCP message to the server
and put the desired recipient as data in the TCP layer which is then
extracted by the server so it knows where to send it?
In an ideal world, the clients could talk to each other directly, since they could find out the IP addresses of the other clients from the server (either via its broadcast or by requesting a list of IP addresses from the server). If all of your clients are running on the same LAN, that can work well.
Assuming you want your system to run on the general Internet, however, that won't work so well, since many/most clients will be behind various firewalls and so they won't accept incoming TCP connections. (There are some ways around that, but they require a very advanced understanding of how TCP works, and even then they only work in certain situations, so I don't recommend attempting them in a first project)
Therefore, for a reliable client->client messaging mechanism, your best bet is indeed to have the sending client send the message to the server, along with some short header that tells the server which other client(s) the message ought to be forwarded to. My own client/server messaging system works along these lines, and I've found it to work well.
I also want to add encryption to the messages which would then no
longer allow the server to read the data, so I'm not sure how to solve
that!?
Don't worry about adding encryption until you've got the basic non-encrypted functionality working first, since encryption will make things much more difficult to debug. That said, it's perfectly possible to pass encrypted/opaque data to the server, as long as the aforementioned header data (which tells the server where to forward the message to) is not encrypted (since the server will need to be able to read the header to know what to do with the encrypted data). The trickier part will be when the receiving client gets the forwarded data from the server -- how will the receiving client know how to decrypt it? You'll need some external mechanism for clients to share keys (either symmetric keys or public/private keypairs), since if you sent the encryption keys themselves through the server, there wouldn't be much point in encrypting anything (since the server could retain a copy of any keys it forwarded, and use them to decrypt, if it wanted to)

Does libcurl able to send a http message over UDP?

I developed a program that makes parameters tracking. I want to inform a server with a http message over udp when a parameter value changes.
I want to use libcurl for that. Does libcurl able to send a http message over UDP?
No it doesn't. For HTTP, libcurl only supports TCP or Unix domain socket. It could possibly be something to add in a future.
(libcurl supports UDP transfers for a few other protocols.)
HTTP could in theory be used over a different protocol than TCP (this case is mentioned in RFC2616), but it needs to be a reliable protocol, that is a protocol which provides guaranteed delivery, must keep the order of messages and must detect duplicates. Plain UDP does not provide these things and thus it is not possible to use HTTP over plain UDP and thus libcurl does not provide it.
If you are interested in a protocol with a syntax close to HTTP, but with support of UDP, then have a look at SIP which is used for VoIP.

Populating source IP address in a raw socket to get a valid response

I am doing some basic network programming using c/c++. What I am trying to do is create packets with headers populated with my own values (instead of kernel) , send packet to some server and get a response. I was able to create the tcp/ip header structures and populate fields such as seq_num etc . As an example, I would send a SYN packet to a host at some port, and check if the host responds with a valid SYN_ACK.
I am wondering what needs to be put in for the source_address and source_port field in the ip/tcp header so that I get a valid response. Using local address (127.0.0.1) won't work right, cause the target machine won't be able to send a response.
I have to use raw_sockets only, can't use SOCK_STREAM etc. Using Linux OS.
The source IP address should be the ip address of interface from which you expect the packet to go out to reach the destination. To make things less complicated the source port can be any free port on your machine.
Also you need to take care of one more thing. Once you get the syn-ack back it will be also handled by the tcp stack of your machine and tcp stack will send a reset in response to that syn-ack. If you are on linux you can use iptables to drop the out going reset.
-MS

Sending arbitrary (raw) packets

I've seen it asked elsewhere but no one answers it to my satisfaction: how can I receive and send raw packets?
By "raw packets", I mean where I have to generate all the headers and data, so that the bytes are completely arbitrary, and I am not restricted in any way. This is why Microsofts RAW sockets won't work, because you can't send TCP or UDP packets with incorrect source addresses.
I know you can send packets like I want to with WinPCAP but you cannot receive raw information with it, which I also need to do.
First of all decide what protocol layer you want to test malformed data on:
Ethernet
If you want to generate and receive invalid Ethernet frames with a wrong ethernet checksum, you are more or less out of luck as the checksumming is often done in hardware, and in the cases they're not, the driver for the NIC performs the checksumming and there's no way around that at least on Windows. NetBSD provides that option for most of it drivers that does ethernet checksumming in the OS driver though.
The alternative is to buy specialized hardware, (e.g. cards from Napatech, you might find cheaper ones though), which provides an API for sending and receiving ethernet frames however invalid you would want.
Be aware that sending by sending invalid ethernet frames, the receiving end or a router inbetween will just throw the frames away, they will never reach the application nor the OS IP layer. You'll be testing the NIC or NIC driver on the receiving end.
IP
If all you want is to send/receive invalid IP packets, winpcap lets you do this. Generate the packets, set up winpcap to capture packets, use winpcap to send..
Be aware that packets with an invalid IP checksum other invalid fields, the TCP/IP stack the receiving application runs on will just throw the IP packets away, as will any IP/layer 3 router inbetween the sender and receiver do. They will not reach the application. If you're generating valid IP packets, you'll also need to generate valid UDP and implement a TCP session with valid TCP packets yourself in order for the application to process them, otherwise they'll also be thrown away by the TCP/IP stack
You'll be testing the lower part of the TCP/IP stack on the receiving end.
TCP/UDP
This is not that different from sending/receiving invalid IP packets. You an do all this with winpcap, though routers will not throw them away, as long as the ethernet/IP headers are ok. An application will not receive these packets though, they'll be thrown away by the TCP/IP stack.
You'll be testing the upperpart of the TCP/IP stack on the receiving end.
Application Layer
This is the (sane) way of actually testing the application(unless your "application" actually is a TCP/IP stack, or lower). You send/receive data as any application would using sockets, but generate malformed application data as you want. The application will receive this data, it's not thrown away by lower protocol layers.
Although one particular form of tests with TCP can be hard to test - namely varying the TCP segments sent, if you e.g. want to test that an application correctly interprets the TCP data as a stream. (e.g. you want to send the string "hello" in 5 segments and somehow cause the receiving application to read() the characters one by one). If you don't need speed, you can usually get that behaviour by inserting pauses in the sending and turn off nagel's algorithm (TCP_NDELAY) and/or tune the NIC MTU.
Remember that any muckery with lower level protocols in a TCP stream, e.g. cause one of the packets to have an invalid/diffferent IP source address just gets thrown away by lower level layers.
You'll be testing an application running on top of TCP/UDP(or any other IP protocol).
Alternatives
switch to another OS, where you at least can use raw sockets without the restrictions of recent windows.
Implement a transparent drop insert solution based on the "Ethernet" or "IP" alternative above. i.e. you have your normal client application, your normal server application. You break a cable inbetween them, insert your box with 2 NICs where you programatically alter bytes of the frames received and send them back out again on the other NIC. This'll allow you to easily introduce packet delays in the system as well. Linux' netfilter already have this capability which you can easily build on top of, often with just configuration or scripting.
If you can alter the receiving application you want to test, have it read data from something else such as a file or pipe and feed it random bytes/packets as you wish.
Hybrid model, mainly for TCP application testing, but also useful for e.g. testing UDP ICMP responses. Set up a TCP connection using sockets. Send your invalid application data using sockets. Introduce random malformed packets(much easier than programming with raw sockets that set up a TCP session and then introduce lower layer errors). Send malformed IP or UDP/TCP packets, or perhaps ICMP packets using WinPcap, though communicate with the socket code to the winpcap code so you'll the addresses/port correct, such that the receiving application sees it.
Check out NS/2

Best way to get data from text (char *)

Hey,
I'm sending messages via TCP and UDP from clients to the server while the server written in C++. I'm wondering what would be the best, must secure way to send, for example, if I want to send login data: email, password and IP. What would be the best way to send it in a message ang read the data in the server, while this data is stored in char *.
Thanks.
This doesn't really have anything to do with C++. You are asking a generic question about information security. You want to send information via TCP or UDP that includes sensitive information (email address, password, and IP). For this you need to use cryptography.
Cryptography is a complicated area where you should not try to roll your own protocols unless you know a lot about what you are doing. Instead, you should avoid UDP (because it is VERY hard to do crypto properly over UDP) and simply use SSL over TCP.
To do this from C++ you can use the OpenSSL sockets library. Both the client and the server link with the library. If you want a little help, you can debug using sslwrap, a command-line tool that allows you to use cleartext sockets from your client & server, but have the unencrypted data wrapped inside an SSL TCP connection.
As another poster stated, don't worry about C++; use SSL or TLS. This means you will need to acquire a certificate for the server, and that will cost you between $50 and $1500 dollars if you get a commercial one, or you can make your own from a intranet certificate authority that you establish yourself.
This measure will encrypt the communication, and ensure that your client is actually "talking" to the authentic server, not an imposter. However, if you need the client to also be authenticated, then you will need a second certificate (possibly one per client machine, to be precise). If that is too heavy-weight for your client needs, then consider using HMAC to help determine an authorized client from an imposter.