network – intercept TCP traffic on compromised router

I have this configuration

GATEWAY1 <----> ROUTER <---> GATEWAY2

I am on the compromised router, and I want to intercept/block the packets that come from G1,edit them , and forward on Gateway 2,acting as a MiTM.
I know that I can edit packets with Scapy, but how I can stop them to reach the original destination?

Gateway 1 and 2 are on Debian "squeeze".
The Router has Kali.

tcpclient – TCP SOCKET image transfering

I’m trying to send .yuv image file through tcp socket but some amount of byte array transfered and image build but not get 100% image it shows only 10% of image. I used Async Task for receive continuously image data in server side.

Here Server Side Code

public class TcpServer extends AppCompatActivity {
    Button btSendData;
    TextView tvDisplayData, tvIp;
    EditText edtInput;
    BufferedWriter outWriter = null;
    private ServerSocket serverSocket;
    boolean isActivityRun = true;
    private int port = 5555;
    byte() message;
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_tcp_server);
        btSendData = findViewById(R.id.bt_send);
        tvDisplayData = findViewById(R.id.tv_display_data);
        tvIp = findViewById(R.id.tv_ip);
        edtInput = findViewById(R.id.edt_input);
        imageView = findViewById(R.id.imgae);
        //Get local Ip address
        WifiManager wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
        // Toast.makeText(this, wm.getConnectionInfo().getIpAddress()+"", Toast.LENGTH_SHORT).show();
        String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
        tvIp.setText(ip);
        //Strict mode policy used for performing network related operation in main thread.
        //Network access on the application's main thread
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        btSendData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (outWriter != null) {
                    try {
                        String data = edtInput.getText().toString() + "rn";
                        outWriter.write(data);
                        outWriter.flush();
                    } catch (Exception e) {
                        Toast.makeText(TcpServer.this, "Client is not connected", Toast.LENGTH_SHORT).show();
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(TcpServer.this, "Client is not connected", Toast.LENGTH_SHORT).show();
                }

            }
        });
        new Thread() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(port);
                    while (isActivityRun) {
                        Socket socket = serverSocket.accept();
                        Log.d("server", socket.getInetAddress() + "");
                        socket.setKeepAlive(true);
                        new IncomingClient().execute(socket);
                    }
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    try {
                        if (serverSocket != null) {
                            serverSocket.close();
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    e.printStackTrace();
                }

            }
        }.start();

    }


    private class IncomingClient extends AsyncTask<Socket, byte(), String> {
        String response = "";
        Socket socket;
        BufferedWriter out;
        byte() buf;
        String data = "";

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "Client Connected", Toast.LENGTH_SHORT).show();
                }
            });

        }

        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        @Override
        protected String doInBackground(Socket... sockets) {

            try {
                socket = sockets(0);
                // Creating new socket connection to the IP (first parameter) and its opened port (second parameter)
                out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                outWriter = out;
                InputStream inputStream = socket.getInputStream();
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // String outMsg = "Client accepted";
                // Write message to stream
                //out.write(outMsg);
                // out.flush();
                // Flush the data from the stream to indicate end of message
//                out.flush();
                String line;
                byte() buffer = new byte(30000);
                int bytes;
                int tot=0;
                byte() b1=null;
               // List<Byte> list = new List<Byte>();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                while ((bytes=inputStream.read(buffer)) != -1) {
                    Log.d("TAGGGG", "bytes  " + bytes);

                    bos.write(buffer, 0, bytes);
                    tot = tot+bytes;

                   // data = data + new String(buffer, StandardCharsets.UTF_8).trim();
                    Log.d("TAGGGG", "length " + tot);
                  /*  if (data.contains("<get_device_info:")){
                        sendData("<,device_info,02:00:00:00:00:00,863077040053161,>");
                    }else if (data.contains("<get_device_status:")){
                        sendData("<,device_status,0,51.73504638671875@59.46295166015625,>");

                    }
*/
                    if(tot>40000) {
                        Log.d("TAG Server","buf "+buffer.length);
                        publishProgress(buffer);
                        tot = 0;
                        Log.d("TAG Server","tot "+tot);
                        bos.flush();
                    }
                }

              /*  while ((line = in.readLine()) != null) {
                    String data = line.trim();
                    Log.d("TAG", "Data:- " + data);

                    byte() encoded = Base64.decode(data, Base64.DEFAULT);


                    if (data.contains("<get_device_info:")){
                        sendData("<,device_info,02:00:00:00:00:00,863077040053161,>");
                    }else if (data.contains("<get_device_status:")){
                        sendData("<,device_status,0,51.73504638671875@59.46295166015625,>");

                    }
                    publishProgress(encoded);
                }*/
                socket.close();
            } catch (Exception ex) {

                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            return response;
        }

        private void sendData(String s) {
            try {
                out.write(s + "nr");
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        protected void onPostExecute(String response1) {
            super.onPostExecute(response1);
            Toast.makeText(getApplicationContext(), "Client Disconnected", Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onProgressUpdate(byte()... values) {
            //Update the progress of current task
            super.onProgressUpdate(values);
            Log.d("values","____________"+values(0));
            // Log.v("response", "" + values(0));
            // tvDisplayData.setText(values(0)
        /*    File  file = new File(Environment.getExternalStorageDirectory(),"/Image.yuv");


            try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(values(0));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }*/
            try {

                byte() b1 = values(0);

              /*  if(buf !=null) {

                    byte() c = new byte(buf.length + b1.length);
                    System.arraycopy(buf, 0, c, 0, buf.length);
                    System.arraycopy(b1, 0, c, buf.length, b1.length);
                    buf = new byte(c.length);
                    buf=c;

                }else{
                    buf=b1;
                }*/
                // if(buf.length==614400) {


                Log.d("Data", "Data length" + b1.length);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                YuvImage yuvImage = new YuvImage(values(0), ImageFormat.YUY2, 640, 480, null);
                yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 100, out);
                byte() imageBytes = out.toByteArray();
                Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
                imageView.setImageBitmap(image);
                //   }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        isActivityRun = false;
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        super.onDestroy();
    }
}

Client Code

public class TcpClient extends AppCompatActivity {

    Button btSendData;
    Button btConnect;
    TextView tvDisplayData;
    EditText edtInput, edtIp;
    BufferedWriter outWriter = null;
    Socket socket;
    boolean isConnect = false;
    AsyncTask<String, String, String> asyncClient;
    String s;
    OutputStream socketOutputStream;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tcp_client);
        btSendData = findViewById(R.id.bt_send);
        btConnect = findViewById(R.id.bt_connect);
        tvDisplayData = findViewById(R.id.tv_display_data);
        edtInput = findViewById(R.id.edt_input);
        edtIp = findViewById(R.id.edt_ip);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        btSendData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (outWriter != null) {
                    File file = new File(Environment.getExternalStorageDirectory(), "/" + "sample_image.yuv");
                    FileInputStream fis = null;
                    try {
                        fis = new FileInputStream(file);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }


                    byte() b1 = null;
                    try {
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();

                        b1 = new byte(fis.available());

                        for (int readNum; (readNum = fis.read(b1)) != -1; ) {
                            bos.write(b1, 0, readNum);

                        }

                        // byte() encoded = Base64.encode(b1, Base64.DEFAULT);


                        socketOutputStream.write(b1);

                        Log.d("TAG", "Length of b1:-  " + b1.length);
                        Log.d("TAG", "client " + b1);
                        socketOutputStream.flush();
                       /* byte() b2={0x0D,0x0A};
                        socketOutputStream.write(b2);
                        socketOutputStream.flush();*/
                    } catch (Exception e) {
                        e.printStackTrace();
                    }


        /*            String str = new String(b1);
                    Log.d("TAG", "___________-------------------___________________");
                    Log.d("TAG", "value" + str);
                    Log.d("TAG", "value" + str.length);
                    Log.d("TAG", "__________--------------------____________________");
*/

                    try {
                        /*outWriter.write(b1);
                        outWriter.flush();*/
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "Please Connect", Toast.LENGTH_SHORT).show();
                }


            }
        });
        btConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("res", "isCon " + isConnect);
                if (!isConnect) {
                    asyncClient = new AsyncClient().execute(edtIp.getText().toString().trim());
                    //asyncClient.cancel(true);
                } else {
//                    btConnect.setText("Connect");
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    Toast.makeText(TcpClient.this, "Disconnect", Toast.LENGTH_SHORT).show();
                }

            }
        });
    }

/*    private byte() readfile(File file) {
        FileInputStream fileInputStream = null;
        byte() bFile = new byte((int) file.length());
        try {
            //convert file into array of bytes
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(bFile);
            fileInputStream.close();
            for (int i = 0; i < bFile.length; i++) {
                System.out.print((char) bFile(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bFile;
    }*/

    private byte() getByte(String path) {
        byte() getBytes = {};
        try {
            File file = new File(path);
            getBytes = new byte((int) file.length());
            InputStream is = new FileInputStream(file);
            is.read(getBytes);
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return getBytes;
    }

    private class AsyncClient extends AsyncTask<String, String, String> {
        String response = "";

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            runOnUiThread(new Runnable() {
                public void run() {
                    isConnect = true;
                    btConnect.setText("Disconnect");
                    Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_SHORT).show();

                }
            });
        }

        @Override
        protected String doInBackground(String... ip) {

            try {
                // Creating new socket connection to the IP (first parameter) and its opened port (second parameter)
                socket = new Socket();// new Socket(Constant.SERVER_IP_TEMP, 8888);//portquiz.net52.47.209.216
                socket.connect(new InetSocketAddress(ip(0).trim(), 5555), 10000);
                //  socket.setSoTimeout(10000);
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                outWriter = out;
                socketOutputStream = socket.getOutputStream();
                //
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String line;
                isConnect = true;
                while ((line = in.readLine()) != null && isConnect) {
                    String data = line;
                    publishProgress(data);
                }
                isConnect = false;
                socket.close();
            } catch (Exception ex) {
                isConnect = false;
                ex.printStackTrace();
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return response;
        }

        @Override
        protected void onPostExecute(String response1) {
            super.onPostExecute(response1);
            btConnect.setText("Connect");
            isConnect = false;
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            isConnect = false;
            if (socket != null) {
                try {
                    socket.close();
                    outWriter = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            Log.v("response", "on Cancel");
        }

        @Override
        protected void onProgressUpdate(String... values) {
            //Update the progress of current task
            super.onProgressUpdate(values);
            Log.v("response", values(0));
            tvDisplayData.setText(values(0));
        }
    }


}

(I got this output when I send image first time1

tcp – Chunked HTTP response does not come through completely

Consider the following setup

 +-------+            +--------+           +----------+
 |       |            |        |           |          |
 |       +----------->+        +---------->+          |
 |       | TCP TUNNEL |        |    HTTPS  |          |
 +-------+            +--------+           +----------+
  User                  SSH Server         Web server

User Performs a HTTP GET request to 127.0.0.1:8888

User is being TCP tunneled from 127.0.0.1:8888 to SSH Server, using SSH port forwarding

User is being TCP tunnel from SSH Server to Web server which responds with Transfer-Encoding: chunked

User receives only first 700KB of data and the connection hangs.

The same thing works perfectly when using a fixed Content-Length.

Investigation

When performing the same HTTP GET request from the SSH server itself – The whole response is received

When performing the same HTTP GET request from another type of TCP tunneling (i.e SOCKS from USER to SSH SERVER) – The user receives only 700kb of data

When performing a HTTP GET request through the tunnel, and the HTTP server responds with a fixed-length body, all of the data is received

The riddle

Where should we start looking? Why does the HTTP GET works perfectly when running directly from SSH server, but does not work when tunneled through it?

TCP Sequence numbers and timeouts

How do sequence numbers and timeouts provide a reliable channel for application-layer data?

ethernet – TCP Master and Slave Socket Open and Close

I have two device one of them Modbus master and another modbus slave.Modbus master working on windows PC. And it polling modbus read query and expects modbus response.

They communicate succesfully when slave powered on , than when I disconnected cable from Windows pc, and connect again they couldnt communicate never. ( Master changed port but slave couldnt close before port, or master couldnt close before port who is responsible for that i dont know)

Data packets like these and it flows forever: (1.40 device slave another master)

enter image description here

Why this happen? I did Modbus TCP Master-Slave this configuration for slave side but it doesnt affect any thing. How can I solve this

beginner – Basic Cpp TCP TLS Client-Server hashing code based on OpenSSL1.1.1 (detailed instruction included)

I wrote ‘Client.cpp’ and ‘Client.cpp’ that do the following.
This is a part of the graduate research assistant screening process.

  1. Create a client and server program communicating over TCP socket.
  2. Establish TLS connection between the client and server
  3. Implement a hash service on the server
  • Take a number from the client
  • Send this number over TLS to the server
  • The server uses the Sha256 hash function within the OpenSSL library to generate a hash code for the number
  • The server sends the hash code back to the client for display.

Any opinion including the following is welcomed:

  • Application of best practices and design pattern usage
  • Potential security issues
  • Performance
  • Correctness in unanticipated cases
  • Scalability
  • Formatting

Code was developed and tested using

  • Ubuntu 20.04
  • OpenSSL 1.1.1
  • g++ 7.5.0

1. install openssl-1.1.1i

1.1. download openssl-1.1.1i here : https://www.openssl.org/source/

1.2 You may follow this instruction on how to install openssl : https://askubuntu.com/questions/1102803/4.how-to-upgrade-openssl-1-1-0-to-1-1-1-in-ubuntu-18-04

NOTE : after download, change ‘openssl-1.1.1g’ into ‘openssl-1.1.1i’

2. Secure a certificate and a private key

Do 2.1 or 2.2

2.1. create your own certificate

openssl req -new -x509 -nodes -config ssl.conf -out cert.pem -keyout key.pem -days 365

ssl.conf is uploaded.

For more information on how to create certificates, see: https://linuxize.com/post/creating-a-self-signed-ssl-certificate/

2.2 use uploaded certificate (cert.pem) and a private key (key.pem)

I know a private key should not be shared. This is only for convenient testing.

3. run code

(Server)

g++ -Wall -o Server Server.cpp -lssl -lm -lcrypto 
I uploaded 'Server'. Therefore, you may skip it. This is only for convenient testing. 

./Server (port) (cert.pem's path) (private key.pem's path) (the number of clients are allowed to request connection) 
./Server 9876 ./cert.pem ./ket.pem 5 

(Client)

g++ -Wall -o Client Client.cpp -lssl -lm -lcrypto 
I uploaded 'Server'. Therefore, you may skip it. This is only for convenient testing. 

./Server (hostname) (port) 
./Client 127.0.0.1 9876 
You can see results in localhost if you enter 127.0.0.1.

You must start Server first. 
The Server's port and the Client's port must be identical. 

reference

  1. socket programming in cpp: https://www.geeksforgeeks.org/socket-programming-cc/
  2. how to compile and debug cpp file in visual studio code : https://code.visualstudio.com/docs/cpp/config-linux
  3. TLS Server : https://wiki.openssl.org/index.php/Simple_TLS_Server
  4. TLS Client : https://gist.github.com/vedantroy/d2b99d774484cf4ea5165b200888e414
  5. openssl and compile : https://stackoverflow.com/questions/8945963/compile-c-and-openssl-on-ubuntu-11-10
  6. code with code review : Send and receive data code using OpenSSL
  7. sha256 : https://stackoverflow.com/questions/2262386/generate-sha256-with-openssl-and-c

Server.cpp

#include <iostream> 
#include <unistd.h> 
#include <string.h>
#include <iomanip>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <openssl/ssl.h>
#include <openssl/err.h>
using namespace std;

SSL_CTX *configure_context() { 
    if(OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL) != 1){
        perror("OPENSSL_init_ssl() failed");
        exit(EXIT_FAILURE);
    }

    const SSL_METHOD *method = SSLv23_server_method();
    if(method == NULL) {
        perror("SSLv23_server_method() failed");
        exit(EXIT_FAILURE);
    }

    // create SSL context
    SSL_CTX *ctx = SSL_CTX_new(method);
    if (!ctx) {
        perror("SSL_CTX_new() failed");
        exit(EXIT_FAILURE);
    }

    // SSL_CTX_set1_curves() sets the supported curves for ctx to clistlen curves in the array clist.
    if(SSL_CTX_set_ecdh_auto(ctx, 1) != 1) {
        perror("SSL_CTX_set_ecdh_auto() failed");
        exit(EXIT_FAILURE);
    }

    return ctx;
}

void configure_keys(SSL_CTX *ctx, char *certificate, char *private_key) {
    if (SSL_CTX_use_certificate_file(ctx, certificate, SSL_FILETYPE_PEM) <= 0) {
        perror("SSL_CTX_use_certificate_file() failed");
        exit(EXIT_FAILURE);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, private_key, SSL_FILETYPE_PEM) <= 0) {
        perror("SSL_CTX_use_PrivateKey_file() failed");
        exit(EXIT_FAILURE);
    }
}

string sha256(const string input) {
    unsigned char hash(SHA256_DIGEST_LENGTH);
    SHA256_CTX sha256;

    // initialize a SHA256_CTX structure.
    if(SHA256_Init(&sha256) != 1) {
        perror("SHA256_Init() failed");
        exit(EXIT_FAILURE);
    }

    // SHA256_Update() is called repeatedly with chunks of the message to be hashed (input.c_str() bytes at input.size()).
    if(SHA256_Update(&sha256, input.c_str(), input.size()) != 1) {
        perror("SHA256_Update() failed");
        exit(EXIT_FAILURE);
    }

    // SHA256_Final() places the message digest in 'hash', 
    // which must have space for SHA256_DIGEST_LENGTH (32) bytes of output, and erases the SHA256_CTX.
    if(SHA256_Final(hash, &sha256) != 1) {
        perror("SHA256_Final() failed");
        exit(EXIT_FAILURE);
    }

    stringstream hash_code;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        hash_code << hex << setw(2) << setfill('0') << (int)hash(i);
    }
    return hash_code.str();
}

int main(int argc, char *argv()) { 
    SSL_CTX *ctx = configure_context();

    configure_keys(ctx, argv(2), argv(3));

    // create a client and server program communicating over TCP socket
    // create a TCP socket
    int server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("socket() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) socket()" << endl;

    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;
    // convert 4 byte-integer into network bytes
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    // convert 2 byte-integer into network bytes
    server_address.sin_port = htons(atoi(argv(1)));

    if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
        perror("bind() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) bind()" << endl;

    if (listen(server_socket, atoi(argv(4))) < 0) {
        perror("listen() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) listen()" << endl;

    // server waits for Client to connect
    while (1) {
        char input(1024) = { 0 };
        char output(1024) = { 0 }; 

        struct sockaddr_in client_address;
        int size_client_address = sizeof(client_address);
        int client_socket = accept(server_socket, (struct sockaddr *)&client_address, (socklen_t *)&size_client_address);
        if (client_socket < 0) {
            perror("accept() failedn");
            exit(EXIT_FAILURE);
        }
        cout << "(current state) accept()" << endl;

        // establish TLS connection between the client and server
        SSL *ssl = SSL_new(ctx);
        if (ssl == nullptr) {
            perror("SSL_new() failedn");
            exit(EXIT_FAILURE);
        }        

        if(SSL_set_fd(ssl, client_socket) != 1) {
            perror("SSL_set_fd() failedn");
            exit(EXIT_FAILURE);
        }

        if (SSL_accept(ssl) <= 0) {
            perror("SSL_accept() failedn");
            continue;
        }

        // get a number from Client
        int read_length = SSL_read(ssl, (char *)input, 1024);
        if (read_length <= 0) {
            perror("SSL_read() failedn");
            continue;
        }

        if (strcmp(input, "(exit)") == 0) {
            cout << "(terminate server)" << endl;
            SSL_free(ssl);
            close(client_socket);
            break;
        }

        // implement a hash service on the server 
        // the server uses the Sha256 hash function within the OpenSSL library to generate a hash code for the number 
        string hash_code = sha256(input);

        // the server sends the hash code back to the client for display. 
        int length = sprintf(output, "(server's hash code): %s", hash_code.c_str());
        int written_length = SSL_write(ssl, output, length);
        if (written_length <= 0) {
            perror("SSL_write() failedn");
            continue;
        } 
        cout << output << endl;
        
        // shut down a TLS/SSL connection
        if(SSL_shutdown(ssl) != 1) {
            perror("SSL_shutdown() failedn");
        }
        // free an allocated SSL structure
        SSL_free(ssl);
        close(client_socket);
    } 

    close(server_socket);
    SSL_CTX_free(ctx);
    // load and free error strings
    ERR_free_strings(); 

    return 0;
}

Client.cpp

#include <iostream>
#include <unistd.h> 
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h> 
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

using namespace std;

const int ERROR_STATUS = -1;

SSL_CTX *configure_context() {
    const SSL_METHOD *method = TLS_client_method();
    if (method == NULL) {
        perror("TLS_client_method() failedn");
        exit(EXIT_FAILURE);
    }

    SSL_CTX *ctx = SSL_CTX_new(method);
    if (ctx == NULL) {
        perror("SSL_CTX_new() failedn");
        exit(EXIT_FAILURE);
    }
    return ctx;
}

void display_certs(SSL *ssl) {
    // get server's certificate
    X509 *cert = SSL_get_peer_certificate(ssl); 
    if (cert == nullptr) {
        perror("SSL_get_peer_certificate() failed. No client certificates configuredn");
        exit(EXIT_FAILURE);
    }

    cout << "(server certificates)" << endl;
    char *line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
    if(line == NULL) {
        perror("X509_NAME_oneline(X509_get_subject_name(), 0, 0) failedn");
        exit(EXIT_FAILURE);
    }
    cout << "subject: " << line << endl;
    delete line;

    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
    if(line == NULL) {
        perror("X509_NAME_oneline(X509_get_issuer_name(), 0, 0) failedn");
        exit(EXIT_FAILURE);
    }
    cout << "issuer: " << line << endl;
    delete line;

    X509_free(cert);
}

int main(int argc, char *argv()) {
    cout << "enter (exit) to end this program" << endl;

    SSL_CTX *ctx = configure_context(); 

    // create an SSL structure for a connection
    SSL *ssl = SSL_new(ctx);
    if (ssl == NULL) {
        perror("SSL_new() failedn");
        exit(EXIT_FAILURE);
    } 

    struct hostent *host = gethostbyname(argv(1));
    if (host == nullptr) {
        perror("gethostbyname() failedn");
        exit(EXIT_FAILURE);
    }

    struct addrinfo hints = {0}, *addrs;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    if (getaddrinfo(argv(1), argv(2), &hints, &addrs) != 0) {
        perror("getaddrinfo() failedn");
        exit(EXIT_FAILURE);
    }

    int client_socket;
    for (struct addrinfo *addr = addrs; addr != nullptr; addr = addr->ai_next) {
        client_socket = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
        if (client_socket == ERROR_STATUS) {
            perror("perror() failedn");
            continue;
        }
        cout << "(current state) socket()n";

        if (connect(client_socket, addr->ai_addr, addr->ai_addrlen) == 0) {
            cout << "(current state) connect()" << endl;
            break; 
        }

        client_socket = ERROR_STATUS;
        close(client_socket);
    }

    freeaddrinfo(addrs);

    if (client_socket == ERROR_STATUS) {
        perror("connect() failedn");
        exit(EXIT_FAILURE);
    }

    // connect the SSL object (ssl) with a file descriptor (client_socket)
    if (SSL_set_fd(ssl, client_socket) != 1) {
        perror("SSL_set_fd() failedn");
        exit(EXIT_FAILURE);
    }

    // initiate the TLS/SSL handshake with an TLS/SSL server
    if (SSL_connect(ssl) != 1) {
        perror("SSL_connect() failedn");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) connected with " << SSL_get_cipher(ssl) << " encryption" << endl;

    // print certificate information which is set by Server
    // I added this to make sure certificate is applied
    display_certs(ssl);

    while (1) {
        // take a number from client
        cout << "(enter a number): ";
        string sent;
        getline(cin, sent);
        if (sent == "") {
            continue;
        }

        // send this number over TLS to the server
        int written_length = SSL_write(ssl, sent.c_str(), sent.length());
        if (written_length <= 0) {
            SSL_get_error(ssl, written_length);
            continue;
        }

        if (strcmp(sent.c_str(), "(exit)") == 0) {
            cout << "(terminate client)" << endl;
            break;
        }

        // a stack can only hold 1024 kilobytes of data
        // to avoid the risk of a stack-overflow, I set array size 1024 
        char input(1024) = { 0 };
        int read_length = SSL_read(ssl, (char *)input, 1024);
        if (read_length <= 0) {
            SSL_get_error(ssl, read_length);
            continue;
        }
        cout << input << endl;
        break;
    }

    close(client_socket);
    SSL_CTX_free(ctx);

    return 0;
}

How does the server get the correct MSS value in the TCP triple handshake

When the client establishes TCP connection with the server, it will report its MSS value during the third handshake. According to my understanding, the MSS value should be obtained by subtraction 40 from the MTU value of its interface. If the MTU value of the client interface is 1500, its MSS value to the server is 1460, which is OK at the client.What I find confusing is that the MSS given by the server to the client seems to dynamically sense the minimum MTU between the server and the client and then subtract 40. For example, if I change the MTU of the router interface between the client and the server to 1400, the MSS given by the server to the client would be 1360;I know that it is possible to detect changes through PMTUD after establishing a TCP connection, but this is happening during the TCP handshake 3, and the server gets the correct MSS value. How is this happening?

server – How to create Virtual COM connection on Linux (using TCP)?

So, I have a Server and a Host.

Server machine runs on Windows 7. It has program, that creates some data and sends it to port 1001 using ser2net util.

The host is running Linux (Debian 10). It has a program, that runs in Wine. The program must receive data from Server. So, I need to create a virtual COM port, that will receive data from server with ip 10.10.30.30 port 1001 Then I’ll push that data to program in Wine.

So, question: How to create serial data port on Linux, that will establish connection with another pc using tcp?

I was trying to use socat:

like that:

socat  pty,link=/dev/comV0,raw  tcp:10.10.30.30:1001

and like that:

socat  pty,link=/dev/comV0,raw,waitslave  tcp:10.10.30.30:1001

But in this case I get an error: the port is already busy. And the connection is dropped the next moment.

And what shall I do to solve that problem???

TCP proxy server for Windows

Does anyone know of a TCP proxy server that I can use for Windows?

Basically I am trying to port-forward packets coming in on one port from my wi-fi interface, to a port on a different computer on the same local network.

I am trying with netsh to achieve this without any success.

Example, I wish to listen to TCP packets arriving on port 3349 of my Windows machine, and forward to port 500 of computer 192.168.9.99

netsh interface portproxy add v4tov4 listenport=3349 connectport=500 connectaddress=192.168.9.99 

This does not work. Wireshark shows me that my device sending to port 3349 of the Windows computer sends, but never gets an acknowledgement back. I have read that using netsh for port-proxying sometimes has many issues. Thanks in advance.

Delay TCP SYN retransmission on Linux

Our application connects to a device on a radio network. The network has to wake up the device before it can communicate which takes about 3 seconds. In this 3 seconds our CentOS (Linux 3.10.0-957.62.1.el7.x86_64 x86_64) machines sends 2 retransmissions of the TCP SYN packet. The retransmission cause problems on the radio network so I’d like to wait with retransmissions for at least 3 seconds.

Lowering tcp_syn_retries doesn’t really change the first retries and gives unwanted behavior when configured below 4 (which is also not advised). It just reduces retries but still follows the same pattern of retries (just less of them).

Setting tcp_frto to 1 and setting tcp_low_latency to 1 did not have the desired effect as found in this article.

A similar question for Windows is posted here

How do I change the TCP SYN retransmission schema on Linux?