⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aenet.cpp

📁 这是一个基于java编写的torrent的P2P源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void
traceRoute(
	JNIEnv*			env,
	jobject			callback,
	unsigned short	trace_id,
	unsigned long	source_ip,
	unsigned long	target_ip,
	unsigned int	send_sock,
	unsigned int	receive_sock,
	bool			ping_mode )
{
	char	receive_buffer[ sizeof(ip_header) + sizeof(icmp_header) + 1024];

	unsigned short source_port = TRACE_ROUTE_BASE_PORT;
	unsigned short target_port = TRACE_ROUTE_BASE_PORT;

	int	seq = 0;

	bool	complete	= false;

	bool	use_udp		= true;
	bool	use_icmp	= true;

	int	ttl;

	if ( ping_mode ){

		ttl = 32;

	}else{

		ttl = 0;
	}

	while( ttl < 33 && ( ping_mode || !complete )){

	
		complete = false;

		if ( !ping_mode ){

			ttl++;
		}

			// try each node up to 3 times

		bool probe_successful = false;

		for (int probe_count=0; probe_count<3 && !( complete || probe_successful); probe_count++){

			int	probe_sequence = seq++;

			if ( !sendTraceRouteMessage( env, trace_id, ttl, send_sock, receive_sock, source_ip, source_port, target_ip, target_port + probe_sequence, use_udp, use_icmp )){
			
					// send failed, exception already reported

				return;
			}

			unsigned long	start_ticks = 0;

			while( !complete ){
		
				int receive_timeout = PROBE_TIMEOUT;

				unsigned long	current_ticks = GetTickCount();

				if ( start_ticks == 0 ){

					start_ticks = current_ticks;

				}else{

					receive_timeout -= ( current_ticks - start_ticks );
				}

				if ( receive_timeout <= 0 ){

					if ( !traceRouteReportTimeout( env, callback, ttl )){

						return;
					}

					break;
				}

				if( setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &receive_timeout, sizeof(receive_timeout)) == SOCKET_ERROR ){

					throwException( env, "setsockopt", "failed to set receive timeout socket options" );

					return;
				}

				struct sockaddr_in from;
				
				int	from_len = sizeof( from );

				unsigned int	read_len  = recvfrom( receive_sock, receive_buffer, sizeof( receive_buffer ), 0, (struct sockaddr *)&from, &from_len );
				
				if ( read_len == SOCKET_ERROR ){
					
					if ( WSAGetLastError() == WSAETIMEDOUT ){

						if ( !traceRouteReportTimeout( env, callback, ttl )){

							return;
						}

						break;

					}else{

						throwException( env, "recvfrom", "operation failed", WSAGetLastError());

						return;
					}

				}else{

					if ( read_len < sizeof( 4 )){

						// printf( "invalid packet read - length < 4\n" );

						continue;
					}

					ip_header	*ip = (ip_header *)receive_buffer;

					unsigned char	ip_len		= ip->ip_header_len << 2;
					unsigned short	total_len	= ntohs( ip->total_len );

						// ensure we have a whole packet and an icmp reply

					if ( read_len != total_len || read_len < ip_len + sizeof(icmp_header)){

						// printf( "invalid packet read - read_len != total_len\n" );

						continue;
					}

					int	elapsed_time = (int)( GetTickCount() - current_ticks );

					icmp_header *icmp = (icmp_header *)(receive_buffer + ip_len );

					unsigned char	icmp_type	= icmp->type;

					if ( icmp_type == ICMP_TYPE_ECHO_REPLY ){

						icmp_echo_header *icmp = (icmp_echo_header *)(receive_buffer + ip_len );

						unsigned short	reply_seq = ntohs( icmp->sequence ) - TRACE_ROUTE_BASE_PORT;

						if ( reply_seq != probe_sequence ){

							continue;
						}

						traceRouteReportResult( env, callback, ttl, ntohl( from.sin_addr.s_addr ), elapsed_time, false );

						if ( ping_mode ){

							use_udp = false;
						}

						complete = true;

						break;
					}

					if ( read_len != total_len || read_len < ip_len + sizeof(icmp_header) + sizeof( ip_header ) + 2){

						// printf( "invalid packet read - read_len != total_len\n" );

						continue;
					}

					
					ip_header* old_ip = (ip_header *)(receive_buffer + ip_len + sizeof( icmp_header ));

					if (	icmp_type != ICMP_TYPE_TTL_EXCEEDED &&
							icmp_type != ICMP_TYPE_UNREACHABLE ){

						// printf( "Unexpected ICMP reply type %d\n", icmp_type );

						continue;
					}
		
					if ( trace_id != ntohs(old_ip->ident )){

							// not our reply

						continue;
					}

					bool	reply_was_udp;

					if ( old_ip->protocol == IPPROTO_ICMP ){

						icmp_probe_packet*	probe = (icmp_probe_packet *)(receive_buffer + ip_len + sizeof( icmp_header ));

						unsigned short	reply_seq = ntohs( probe->icmp.sequence ) - TRACE_ROUTE_BASE_PORT;

						if ( reply_seq != probe_sequence ){

							continue;
						}

						reply_was_udp = false;

					}else{
					
						udp_probe_packet*	probe = (udp_probe_packet *)(receive_buffer + ip_len + sizeof( icmp_header ));

						unsigned short	reply_seq = ntohs( probe->udp.dest_port ) - TRACE_ROUTE_BASE_PORT;

						if ( reply_seq != probe_sequence ){

							continue;
						}

						reply_was_udp = true;
					}

					probe_successful = true;

					if ( icmp_type == ICMP_TYPE_ECHO_REPLY ){

						complete = true;

					}else if ( icmp_type == ICMP_TYPE_TTL_EXCEEDED ){
					

					}else if ( icmp_type == ICMP_TYPE_UNREACHABLE ){

						unsigned char	icmp_code	= icmp->code;

						if (	icmp_code == ICMP_CODE_PROTOCOL_UNREACHABLE ||
								icmp_code == ICMP_CODE_PORT_UNREACHABLE ){

								// these are received from the target host

							complete	= true;

						}else{

						}		   
					}

					if ( ping_mode ){

						if ( reply_was_udp ){

							use_icmp = false;

						}else{

							use_udp = false;
						}
					}

					if ( !traceRouteReportResult( env, callback, ttl, ntohl( from.sin_addr.s_addr ), elapsed_time, reply_was_udp )){

						return;
					}


					break;
				}
	
			}	
		}
	}

	return;
}


JNIEXPORT void JNICALL 
Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_traceRoute(
	JNIEnv*		env,
	jclass		cla, 
	jint		trace_id,
	jint		source_ip,
	jint		target_ip,
	jint		ping_mode,
	jobject		callback )
{
	initialiseWinsock();

	int receive_sock = socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );

	if ( receive_sock == SOCKET_ERROR ) {

		throwException( env, "socket", "failed to create receive socket" );

		return;
	}

	int receive_timeout = PROBE_TIMEOUT;

	if( setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &receive_timeout, sizeof(receive_timeout)) == SOCKET_ERROR ){

		closesocket(receive_sock);

		throwException( env, "setsockopt", "failed to set receive timeout socket options" );

		return;
	}

	int so_reuseaddress = 1;

	if( setsockopt(receive_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &so_reuseaddress, sizeof(so_reuseaddress)) == SOCKET_ERROR ){

		closesocket(receive_sock);

		throwException( env, "setsockopt", "failed to set receive reuse address socket options" );

		return;
	}

		// we have to bind the socket before we can receive ICMP messages on it
	
	struct sockaddr_in				recv_bind_addr;

	recv_bind_addr.sin_family		= AF_INET;
	recv_bind_addr.sin_addr.s_addr	= htonl( source_ip );
	recv_bind_addr.sin_port			= 0;

	if ( bind( receive_sock, (struct sockaddr *)&recv_bind_addr, sizeof( recv_bind_addr )) == SOCKET_ERROR ){

		closesocket(receive_sock);
	
		throwException( env, "socket", "failed to bind send socket" );

		return;
	}


	int send_sock = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );

	if ( send_sock == SOCKET_ERROR ) {

		closesocket(receive_sock);
	
		throwException( env, "socket", "failed to create send socket" );

		return;
	}

	int	enable = 1;

	if ( setsockopt(send_sock, IPPROTO_IP, IP_HDRINCL, (char *)&enable,sizeof(enable)) == SOCKET_ERROR ){

		closesocket(send_sock);
		closesocket(receive_sock);

		throwException( env, "setsockopt", "failed to set receive socket options" );

		return;
	}


	traceRoute( env, callback, (unsigned short)trace_id, (unsigned long)source_ip, (unsigned long)target_ip, send_sock, receive_sock, ping_mode==1?true:false );

	closesocket(send_sock);
	closesocket(receive_sock);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -