\begin{code} {-# LANGUAGE StrictData #-} module Tox.Network.TCP.Client where \end{code} \chapter{TCP client} \texttt{TCP client} is the client for the TCP server. It establishes and keeps a connection to the TCP server open. All the packet formats are explained in detail in \texttt{TCP server} so this section will only cover \texttt{TCP client} specific details which are not covered in the \texttt{TCP server} documentation. TCP clients can choose to connect to TCP servers through a proxy. Most common types of proxies (SOCKS, HTTP) work by establishing a connection through a proxy using the protocol of that specific type of proxy. After the connection through that proxy to a TCP server is established, the socket behaves from the point of view of the application exactly like a TCP socket that connects directly to a TCP server instance. This means supporting proxies is easy. \texttt{TCP client} first establishes a TCP connection, either through a proxy or directly to a TCP server. It uses the DHT public key as its long term key when connecting to the TCP server. It establishes a secure connection to the TCP server. After establishing a connection to the TCP server, and when the handshake response has been received from the TCP server, the toxcore implementation immediately sends a ping packet. Ideally the first packets sent would be routing request packets but this solution aids code simplicity and allows the server to confirm the connection. Ping packets, like all other data packets, are sent as encrypted packets. Ping packets are sent by the toxcore TCP client every 30 seconds with a timeout of 10 seconds, the same interval and timeout as toxcore TCP server ping packets. They are the same because they accomplish the same thing. \texttt{TCP client} must have a mechanism to make sure important packets (routing requests, disconnection notifications, ping packets, ping response packets) don't get dropped because the TCP socket is full. Should this happen, the TCP client must save these packets and prioritize sending them, in order, when the TCP socket on the server becomes available for writing again. \texttt{TCP client} must also take into account that packets might be bigger than the number of bytes it can currently write to the socket. In this case, it must save the bytes of the packet that it didn't write to the socket and write them to the socket as soon as the socket allows so that the connection does not get broken. It must also assume that it may receive only part of an encrypted packet. If this occurs it must save the part of the packet it has received and wait for the rest of the packet to arrive before handling it. \texttt{TCP client} can be used to open up a route to friends who are connected to the TCP server. This is done by sending a routing request to the TCP server with the DHT public key of the friend. This tells the server to register a \texttt{connection\_id} to the DHT public key sent in the packet. The server will then respond with a routing response packet. If the connection was accepted, the \texttt{TCP client} will store the \texttt{connection id} for this connection. The \texttt{TCP client} will make sure that routing response packets are responses to a routing packet that it sent by storing that it sent a routing packet to that public key and checking the response against it. This prevents the possibility of a bad TCP server exploiting the client. The \texttt{TCP client} will handle connection notifications and disconnection notifications by alerting the module using it that the connection to the peer is up or down. \texttt{TCP client} will send a disconnection notification to kill a connection to a friend. It must send a disconnection notification packet regardless of whether the peer was online or offline so that the TCP server will unregister the connection. Data to friends can be sent through the TCP relay using OOB (out of band) packets and connected connections. To send an OOB packet, the DHT public key of the friend must be known. OOB packets are sent in blind and there is no way to query the TCP relay to see if the friend is connected before sending one. OOB packets should be sent when the connection to the friend via the TCP relay isn't in an connected state but it is known that the friend is connected to that relay. If the friend is connected via the TCP relay, then normal data packets must be sent as they are smaller than OOB packets. OOB recv and data packets must be handled and passed to the module using it.