Clamp MSS of IPv4 SYN packets.
Some ISPs block the ICMP Fragmentation Needed packets that tinc sends. We clamp the MSS of IPv4 SYN packets to prevent hosts behind those ISPs from sending too large packets.
This commit is contained in:
		
							parent
							
								
									e4812ba9cc
								
							
						
					
					
						commit
						2a538ed343
					
				
					 1 changed files with 53 additions and 0 deletions
				
			
		
							
								
								
									
										53
									
								
								src/route.c
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								src/route.c
									
										
									
									
									
								
							|  | @ -93,6 +93,53 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) { | |||
| 		return true; | ||||
| } | ||||
| 
 | ||||
| void clamp_mss(node_t *source, node_t *via, vpn_packet_t *packet) { | ||||
| 	int i; | ||||
| 	int len = ((packet->data[46] >> 4) - 5) * 4; | ||||
| 
 | ||||
| 	for(int i = 0; i < len;) { | ||||
| 		if(packet->data[54 + i] == 0) | ||||
| 			break; | ||||
| 
 | ||||
| 		if(packet->data[54 + i] == 1) { | ||||
| 			i++; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(i > len - 2 || i > len - packet->data[55 + i]) | ||||
| 			break; | ||||
| 
 | ||||
| 		if(packet->data[54 + i] != 2) { | ||||
| 			if(packet->data[55 + i] < 2) | ||||
| 				break; | ||||
| 			i += packet->data[55 + i]; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(packet->data[55] != 4) | ||||
| 			break; | ||||
| 
 | ||||
| 		uint16_t oldmss = packet->data[56 + i] << 8 | packet->data[57 + i]; | ||||
| 		uint16_t newmss = via->mtu - 54; | ||||
| 		uint16_t csum = packet->data[50] << 8 | packet->data[51]; | ||||
| 
 | ||||
| 		if(oldmss <= newmss) | ||||
| 			break; | ||||
| 		 | ||||
| 		ifdebug(TRAFFIC) logger(LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss); | ||||
| 
 | ||||
| 		packet->data[56 + i] = newmss >> 8; | ||||
| 		packet->data[57 + i] = newmss & 0xff; | ||||
| 		csum ^= 0xffff; | ||||
| 		csum -= oldmss; | ||||
| 		csum += newmss; | ||||
| 		csum ^= 0xffff; | ||||
| 		packet->data[50] = csum >> 8; | ||||
| 		packet->data[51] = csum & 0xff; | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void swap_mac_addresses(vpn_packet_t *packet) { | ||||
| 	mac_t tmp; | ||||
| 	memcpy(&tmp, &packet->data[0], sizeof tmp); | ||||
|  | @ -328,6 +375,9 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if(via && via != myself && packet->data[23] == 6 && packet->len >= 58 && (packet->data[46] >> 4) > 5) | ||||
| 		clamp_mss(source, via, packet); | ||||
|   | ||||
| 	send_packet(subnet->owner, packet); | ||||
| } | ||||
| 
 | ||||
|  | @ -740,6 +790,9 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(via && via != myself && (packet->data[12] << 8 | packet->data[13]) == ETH_P_IP && packet->len >= 58 && packet->data[23] == 6 && (packet->data[46] >> 4) > 5) | ||||
| 		clamp_mss(source, via, packet); | ||||
|   | ||||
| 	send_packet(subnet->owner, packet); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue