Detailed TCP connection reset function and achieve end function

We finished on a TCP three-way handshake principle, when the three-way handshake by the two sides exchanged information on the parameters for each transfer, the two sides into a data distribution mode, said that both sides have entered the ESTABLISHED state on the TCP protocol. Based on the early low-quality data transmission network, the connection is established only the beginning, to maintain the stability and smoothness in the communication process is an important part of the TCP protocol.

Since the TCP protocol aimed at maintaining stable long-term data transmission, so it must respond effectively to a sudden interruption in the connection process conditions. Sudden interruption of the most common is called "half-open" process, that is, one party has been disconnected and the other did not know, it is saying that the other party in the normal transmission of data. In order to face this situation, TCP introduced the Reset function, we encoded on a complete three-way handshake, if you observe capture, code and we did not issue a reset packet, but they found us capture issued a reset packet, it is because he reset message will be sent as soon as the other party that the other did not follow the "routine the cards."

In the section of our coding implementation, we like each other when sending a SYN packet, the other party to respond to the ACK packet, since we directly bypass the underlying TCP module, the underlying operating system TCP module will feel confused, two reasons make TCP reset module sends a packet, when one is received SYN packet, TCP module does not find a corresponding process using a respective port for data reception, then he will reset packet occurs, the one we this is the case the second is the other key parameter does not reply upon receipt of an ACK packet.

When the other party receives the reset packets are not directly disconnected, but other tests sent to the reset is reasonable, if the receiver finds that reset packet is reasonable, it will be made to deal with many different according to their current status . If the receiver is in the listening state, then it will maintain the current status unchanged, the other party if the receive direction sent a SYN + ACK packet, but does not receive the ACK packet was received reset packet, then it will return to the listening state, recipient will cut off the current connection in other cases.

In order to prevent our application to bypass the operating system underlying TCP three-way handshake module caused the problem it sends a packet to the other rest on mac we can specify that the TCP module specified IP and port RST packet does not happen right, it follows :
1, first open a file by editing /etc/pf.conf the sudo
2, adding a line in the file:
Block TCP proto drop from 192.168.2.243 to the flags R & lt 220.181.43.8 / R & lt
where 192.168.2.243 ip party is sent to be into your running program ip, 220.181.43.8 is the other ip, you can replace tcp ip want to interact.
Pfctl (8) 3. Run sudo - f /etc/pf.conf
4. Run the command sudo pfctl -e make the settings take effect.

After performing the above steps, we run on a code capture wireshark will not always see the underlying TCP reset packet to the other module transmission. In the TCP protocol data transmission management process also need to control the connection of the "idle" process, that is, when the two sides remain connected but no data is sent or received. If no data is transmitted for a long time, both sides need to ensure that the protocol is still connected in the normal state, then the TCP stack implemented on the operating system does not contain a null message is sent to any other data, then the other replies an ACK packet, with this in the show "is still online" news package called "keepalive" mechanism.

This mechanism does not belong to the TCP protocol TCP agreement but added their own specific mechanisms to achieve party. This mechanism has a lot of debate, but supports server side that is necessary to use keepalive way to ensure the validity of the connection, because the server is connected to simultaneously receive many clients, so each connection means loss of server resources, the server if the connection fails to disconnect a timely manner, so that the resources left to other clients.

When all the data has been sent, the two sides entered the connection is interrupted stage. The problem is that TCP connection to interrupt the process complicated than imagined, which we also mentioned earlier. When the other party to the communication want to close the connection request is issued, this means that it no longer sends data to the other, but it flew off the assembly line can not, because someone may have data to send to yourself, so it must wait for all the other data transfer complete after order off the assembly line.

Thus on one end initiate a connection, it sends a FIN packet to each other, even the packet may also be sent to carry each other's data. Party that receives the FIN packet is sent FIN + ACK packet to the other, then the other side again transmits the ACK packet, considered over the entire communication process.

Next we add a function to close the connection on the basis of one of the corresponding code is as follows:

public class TCPThreeHandShakes extends Application{
....
//增加协议状态标量
	private static int CONNECTION_IDLE = 0;
	private static int CONNECTION_INIT = 1;
	private static int CONNECTION_SUCCESS = 2;
	private static int CONNECTION_FIN_INIT = 3;
	private static int CONNECTION_FIN_SUCCESS = 4;
	private int  tcp_state = CONNECTION_IDLE;
....
 //向服务器发起关闭流程
   public void beginClose() throws Exception {
//	   this.seq_num += 1;
	   createAndSendPacket(null, "FIN,ACK");
	   this.tcp_state = CONNECTION_FIN_INIT;
   }

 @Override
	public void handleData(HashMap<String, Object> headerInfo) {
	   short src_port = (short)headerInfo.get("src_port");
	   System.out.println("receive TCP packet with port:" + src_port);
	   boolean ack =  false, syn = false, fin = false;
	   if (headerInfo.get("ACK") != null) {
		   System.out.println("it is a ACK packet");
		   ack = true;
	   }
	   if (headerInfo.get("SYN") != null) {
		   System.out.println("it is a SYN packet");
		   syn = true;
	   }
	   if (headerInfo.get("FIN") != null) {
		   System.out.println("it is a FIN packet");
		   fin = true;
	   }
	   if (ack && syn) {
		   int seq_num = (int)headerInfo.get("seq_num");
		   int ack_num = (int)headerInfo.get("ack_num");
		   System.out.println("tcp handshake from othersize with seq_num" + seq_num + " and ack_num: " + ack_num);
		   this.seq_num += 1;
		   this.ack_num = seq_num + 1;
		   try {
			if (this.tcp_state == CONNECTION_INIT) {
				this.tcp_state = CONNECTION_SUCCESS;
				System.out.println("three hanshake complete");
			}
			createAndSendPacket(null, "ACK");
			//启动关闭流程
			beginClose();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	   }
	  //收到服务器发回的fin+ack包,正式关闭连接
	  if (ack && fin) {  
		  System.out.println("receive fin packet and close connection");
		  if (this.tcp_state == CONNECTION_FIN_INIT) {
				this.tcp_state = CONNECTION_FIN_SUCCESS;
				System.out.println("three hanshake shutdown");
				 try { 
					   int seq_num = (int)headerInfo.get("seq_num");
					   int ack_num = (int)headerInfo.get("ack_num");
					   System.out.println("tcp handshake closing from othersize with seq_num" + seq_num + " and ack_num: " + ack_num);
					   this.seq_num += 1;
					   this.ack_num = seq_num + 1;
						createAndSendPacket(null, "ACK");
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}
	  }
	  	   
   }
}

In the above code, we add a function BeginClose () for transmitting data packets ACK + FIN inform them close to each other the current connection. This function we complete the three-way handshake after the call, when we want each other to send ACK + FIN packet, the other will send ACK + FIN packet to us, we send a final ACK packet to each other again, thereby completing the TCP Close connection process, after the above code capture operation is shown below:

Screenshot 4.08.34.png 2019-09-17 PM

Ethereal from the results we have successfully completed the three-way handshake and the entire cycle the connection is closed

Published 341 original articles · won praise 247 · views 390 000 +

Guess you like

Origin blog.csdn.net/tyler_download/article/details/100932863