computer networks – TCP congestion control problem

Assume that the maximum transmission window size for a TCP connection is 12000 bytes. Each packet consists of 2000 bytes. At some point, the connection is in a slow start phase with a current 4000 byte transmission window. Subsequently, the transmitter receives two acknowledgments. Assume no packets are lost and there are no waiting times. What is the maximum possible value of the current transmission window?

A) 4000 bytes

B) 8000 bytes

C) 10,000 bytes

D) 12000 bytes

In the congestion control algorithm, when we are in the slow start phase, after 1RTT (round trip time) if the window size exceeds the threshold when doubling, we set cwnd (current window size) = threshold or cwnd = 2 * cwnd?

How to solve this problem?

haskell: read the HTTP header of the TCP socket

I am growing a web server in Haskell that interacts with TCP sockets using the network. To read the HTTP header of the client message, I use the following function:

import           Network.Socket          hiding ( recv )
import           Network.Socket.ByteString      ( recv )

import qualified Data.ByteString               as S
import           Data.ByteString.UTF8          as BSU ( fromString )

readHeader :: Socket -> IO S.ByteString
readHeader sock = go sock mempty
where
  go sock prevContent = do
    newContent <- recv sock maxNumberOfBytesToReceive
    let content = prevContent <> newContent
    -- Read the data from the socket unless it's empty which means
    -- that the client has closed its socket or we see an empty line
    -- which marks the end of the HTTP header
    if S.null newContent || emptyLine `S.isSuffixOf` content
      then return content
      else go sock content
  where
    -- Only read one byte at a time to avoid reading further than the
    -- empty line separating the HTTP header from the HTTP body
    maxNumberOfBytesToReceive = 1
    emptyLine                 = BSU.fromString "rnrn"

The function only reads one byte at a time, since I want to be able to read the rest of the client message from the socket later. But I'm curious to know if the function could be more efficient.

My first idea was to read more bytes (say 1024) from the socket, check if those bytes contain an empty line, save that part (the HTTP header) in a ByteString and put the bytes after the empty line back into the socket buffer. But I am not sure if it is possible or prudent to put the data back in the socket buffer.

I am also interested in any other code enhancement you can think of.

The whole project is here.

start with stack ghci and then run main. Send you an HTTP request with curl http://localhost:8080/

linux: forward TCP traffic through the computer

I have a computer (A) that makes a request to a web service. It is not connected by a cable to the router, but it is on the same LAN as another computer (B) that has 2 network interfaces (one at lan 172.25.0.0/23 (enp27s0) and the other connected to a router 192.168. 255.0 / 24 (enp29s0)).

I can connect and receive a response if I make the request from computer B (I have added a route on computer B) but not if I make the request from computer A.

I have this configuration:

  1. Computer A:

default via 172.25.0.1 dev ens192 proto static metric 100
172.25.0.0/23 dev ens192 proto kernel scope link src 172.25.1.24 metric 100
217.xxx.yyy.0/24 via 172.25.1.14 dev ens192

  1. Computer B:

default via 172.25.0.1 dev enp27s0 proto static metric 100
default via 192.168.255.2 dev enp29s0 proto static metric 101
172.25.0.0/23 dev enp27s0 proto kernel scope link src 172.25.1.14 metric 100
192.168.255.0/24 dev enp29s0 proto kernel scope link src 192.168.255.14 metric 100
217.xxx.yyy.0/24 via 192.168.255.2 dev enp29s0 proto static metric 99

On computer B, I tried to insert this iptables configuration and the computer has ipv4 forwarding enabled:

iptables -A FORWARD -i enp27s0 -o enp29s0 -p tcp --syn --dport 8080 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i enp27s0 -o enp29s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i enp29s0 -o enp27s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -i enp27s0 -p tcp --dport 8080 -j DNAT --to-destination 217.124.156.199
iptables -t nat -A POSTROUTING -o enp29s0 -p tcp --dport 8080 -d 172.25.1.24 -j SNAT --to-source 172.25.1.14
root@joaquin2:~# iptables -A PREROUTING -t nat -i enp27s0 -p tcp --dport 8080 -j DNAT --to-destination 172.25.1.14:8080
iptables -A FORWARD -p tcp -d 172.25.1.14 --dport 8080 -j ACCEPT
iptables -A POSTROUTING -t nat -s 172.25.1.14 -o enp27s0 -j MASQUERADE

If I execute a traceroute command on computer A, this is the result obtained:

traceroute webservice.example.com
traceroute to webservice.example.com (217.xxx.yyy.199), 30 hops max, 60 byte packets
1 172.25.1.14 (172.25.1.14) 0.309 ms 0.231 ms 0.200 ms
2 * * *
3 * * *
4 * * *
5 * * *
6 * * *

But I can't receive an answer. It seems that the request stops on computer B.

To clarify, I attach an image:

Detailed diagram

On both computers, I have Debian 9 Linux.

python 3.x: check the tool that runs the tcp server using the systemd service to obtain logic, implementation and correction

I have written this TCP server in python that runs on a specific port and listens only to a client connection from a microcontroller.

The job of the TCP server is to continuously listen to the client connection and receive data that the tcp server driver loads into mysql in the same localhost.

The logic of the TCP server: home_iot / tcpserver.py

import socket
import sys
import ast
import core
try:
    import fcntl
except ImportError:
    fcntl = None
import logging
import json

server_address = ("192.168.1.110", 7138)
_LOG = logging.getLogger(__name__)

if sys.version_info.major == 2:
    import SocketServer
    TCPServer = SocketServer.TCPServer
    StreamRequestHandler = SocketServer.StreamRequestHandler
if sys.version_info.major == 3:
    import socketserver
    TCPServer = socketserver.TCPServer
    StreamRequestHandler = socketserver.StreamRequestHandler


class ParticlePhotonRequestHandler(StreamRequestHandler):

    def handle(self):
        """Receives data from client.
        """
        msg = self.rfile.readline().strip()
        if self.client_address and not msg:
            _LOG.error("No Data revieved from Client: {}".format(self.client_address(0)))
            return
        _LOG.debug("Received data from client, {}".format(msg.decode('utf-8')))
        # Send some data to client
        self.wfile.write("Hello Client....Got your message".encode())
        data = ast.literal_eval(msg.decode('utf-8'))
        if data:
            _LOG.info("Temperature: %s Humidity: %s", data("temp"), data("humidity"))
        else:
            _LOG.error("No data recieved from particle photon.")
        with core._connect() as conn:
            if conn:
                _LOG.info("Connected to mysql server")
                core.insert_row(data, conn)
                conn.close()


class Server(TCPServer):
    allow_reuse_address = True
    # The constant would be better initialized by a systemd module
    SYSTEMD_FIRST_SOCKET_FD = 3

    def __init__(self, server_address, handler_cls, bind_and_activate=True):
        self.handlers = set()
        # Invoke base but omit bind/listen steps (performed by systemd activation!)
        try:
            TCPServer.__init__(self, server_address, handler_cls, bind_and_activate)
        except TypeError:
            TCPServer.__init__(self, server_address, handler_cls)

        # Override socket
        self.socket = socket.fromfd(
            self.SYSTEMD_FIRST_SOCKET_FD, self.address_family, self.socket_type)

        if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
            flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
            flags |= fcntl.FD_CLOEXEC
            fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)

    def server_close(self):
        TCPServer.server_close(self)
        for handler in self.handlers.copy():
            self.shutdown_request(handler.request)


def main():
    """Starts TCPServer.
    """
    logging.basicConfig(level=logging.DEBUG)
    # Create a TCP Server instance
    server = Server(server_address, ParticlePhotonRequestHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == '__main__':
    main()

The SystemdL service unit
$ HOME / .config / systemd / user / photon_uploader.service

(Unit)
Description=TCP Server to recieve data from Particle Photon to upload to MySql.
After=multi-user.target
Wants=network-online.target
After=network.target photon_uploader.socket
Requires=photon_uploader.socket

(Service)
Type=idle
Restart=always
RestartSec=6
EnvironmentFile=/home/rock64/.config/systemd/user/photon_uploader.env
ExecStart=/usr/bin/python3 /usr/local/iot/home_iot/tcpserver.py
StandardOutput=file:/var/log/user/photon_uploder.log
StandardError=file:/var/log/user/photon_uploader_error.log
TimeoutStopSec=5

(Install)
WantedBy=multi-user.target

and the socket file:

(Unit)
Description=Socket for Particle Photon uploader to MySql Service
PartOf=photon_uploader.service

(Socket)
ListenStream=127.0.0.1:7138

(Install)
WantedBy=sockets.target

Python code, if executed independently, works and updates the data of the particle photon microcontroller to the mysql server.

if we start on systemd the service works fine and starts the tcp server, but the data is not loaded on the mysql server . (I don't understand what is happening here).

There is nothing in the log file. Except the old crawl errors.

Any help will be greatly appreciated for the improvement and correction of the code that I missed. This is my first TCP server and first systemd service.

TCP default maximum segment size

Why is the default maximum TCP segment size 536? If you find this line in TCP / IP by behrouz forouzan

iptables – Rpi as a transparent bridge with redirection of a TCP port

I have a Raspberry Pi with the latest version of Kali Linux Armf.
What I have done so far is to create a br0 with eth1 and eth2.
This works perfectly.
As you can see, I am using two ethernet dongles in my RPi. (leaving eth0 out)
The wlan0 is connected to my router, where I can SSH in the box.

What I want to do is with Iptables or ebtables, intercept port 8509 and send that traffic to burpsuite on my 192.168.1.X machine that runs burp on 0.0.0.0:8080. This belching machine is in my network wlan0 192.168.1.0/24.

How can I achieve that? It's possible?
Maybe having the burpsuite in my Rpi is also an option.

man in the middle – What are the security concerns about using keepalive TCP without encrypting with TLS?

In my software, both the server and the client send unencrypted TCP alert messages to detect the broken pipe in a reasonable time. It also uses TLS 1.3 encryption with OpenSSL 1.1.1.

Is there any safety concern about this?

For example: the Man-in-the-middle attacker interrupts the communication. To supplant on both sides that the connection is still alive, periodically send / forward TCP keepalives.

Is this scenario possible? It is probable?

What other scenario do you think of?

How to receive two clients in Java with TCP?

The problem is this: the algorithm should receive two clients on the server and show who came first, but I cannot receive more than one client, what should I do?

(I took the imports to get a smaller code)

Server:

public class Servidor {

    public static void main(String() args)
            throws IOException, ClassNotFoundException {
        System.out.println("Iniciando o servidor...");
//Do lado servidor a criação do socket
        int porta = 6789;
        // socket do tipo servidor
        ServerSocket socketServidor = new ServerSocket(porta);

        System.out.println("Aguardando conexão...");
//Obter a requisicao do lado cliente
// fica verificando se ha conexoes do cliente
        Socket socketCliente = socketServidor.accept();
        ObjectInputStream entrada = 
                new ObjectInputStream(socketCliente.getInputStream());
        ObjectOutputStream saida
                = new ObjectOutputStream(
                        socketCliente.getOutputStream());

        while(true) {

            String respostaCliente = (String) entrada.readObject();

            System.out.println("Cliente: " + socketCliente.getInetAddress().getHostName() 
                                + respostaCliente);

            if("FIM".equalsIgnoreCase(respostaCliente)) {
                break;
            }
        }
        entrada.close();
        saida.close();
        socketCliente.close();
        socketServidor.close();
    }
}

Client:

public class Cliente {

    public static void main(String() args) throws UnknownHostException, IOException, ClassNotFoundException {

        System.out.println("Iniciando o cliente...");
        System.out.println("Iniciando conexão com o servidor...");

        // só vai avançar quando houver conexão
        Socket socketCliente = new Socket("127.0.0.1", 6789);
        System.out.println("Conexão estabelecida.");

        // escreve no servidor
         ObjectOutputStream saida = new ObjectOutputStream(
                           socketCliente.getOutputStream());

         // recebe (lê) do servidor
         ObjectInputStream entrada = new ObjectInputStream(
                        socketCliente.getInputStream());

         Scanner leitor = new Scanner(System.in);

         while(true) {
             System.out.println("Você é o primeiro! Prefere X ou O?: ");
             String mensagem = leitor.nextLine();
             // escreve no servidor o que o usuario informou
             saida.writeObject(mensagem);

             // quando o usuario escrever "FIM"
             // finaliza a jogada
             if("FIM".equalsIgnoreCase(mensagem)) {
                 break;
             }
         }

         // so fecha tudo quando o usuario escrever FIM
         saida.close();
         entrada.close();
         socketCliente.close();
    }
}

linux – TCP relay stuck

TCP retransmissions stuck

I have the tcp client and server running on Ubuntu 14.04 (kernel 3.13.0-170-generic). The client loads data to the server. If a large amount of data is lost during the transfer (for example, 60 TCP segments, 1460 bytes each), my client cannot retransmit TCP segments.
After each retransmission, the client also sends 2 unattended segments and then waits for the RTO time. Finally, RTO is equal to 120 seconds and my client retransmits a segment every 2 minutes until these 60 lost segments are retransmitted. After that everything goes well again.
TCP Dump Screen Capture

SACK is disabled, here is an output of ss -i (Where is the cwnd value?):

tcp    ESTAB      0      436150    192.168.3.10:51530     198.73.21.200:9081    
 cubic wscale:7,7 rto:120000 rtt:80.5/10 ato:40 mss:1460 ssthresh:2 send 290.2Kbps unacked:272 retrans:0/34 lost:270 rcv_space:29200

So, the question: is it appropriate behavior of the TCP protocol? These retransmissions could take a long time and dramatically decrease performance.

buffer overflow – reverse TCP – Link to a specific port

So, I am trying to solve a CTF challenge that involves exploiting a remote service. The service does not verify the size of the entry and there is a buffer overflow vulnerability. However, before I can hijack the flow of control to my shellcode, the program closes the connection. So, I'm trying to get my shellcode to reconnect with me. A small obstacle is that the server allows outgoing connections only through port 4444. So, my shellcode does the following

  1. socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  2. bind(socket_fd, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("0.0.0.0")}, 16)
  3. connect(socket_fd, {sa_family=AF_INET, sin_port=htons(port_no), sin_addr=inet_addr("ip")}, 16)

I am trying to get a reverse TCP session and I believe that when linking to port 4444 the outgoing connection will go through 4444. While the exploit works on my local system, the remote exploit does not work. Any ideas on what I'm missing or what I should consider? Thank you!