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

📄 sestsconnectionimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
								pending_size =  (( pending_size + AES_KEY_SIZE_BYTES -1 )/AES_KEY_SIZE_BYTES)*AES_KEY_SIZE_BYTES;
								
								if ( pending_size == 0 ){
									
									pending_size = AES_KEY_SIZE_BYTES;
								}
							}
							
							if ( out_buffer.remaining() >= pending_size ){
								
								if ( outgoing_cipher != null ){
									
									
									out_buffer.put( outgoing_cipher.doFinal( pending_bytes ));
									
								}else{
								
									out_buffer.put( pending_bytes );
								}
								
									// don't deallocate the pending message, the original caller does this
																
								pending_message	= null;
							}
						}
						
						crypto_completed	= true;
						
					}else{
							// we've received
							//		a -> autb + data -> b
						
							// read their auth
						
						sts_engine.putAuth( in_buffer );

							// check we wanna talk to this person
						
						byte[]	rem_key = sts_engine.getRemotePublicKey();
						
						if ( !key_locator.accept( new SEPublicKeyImpl( my_public_key.getType(), rem_key ))){
							
							throw( new MessageException( "remote public key not accepted" ));
						}
						
						setupBlockCrypto();

						crypto_completed	= true;
						
							// pick up any remaining data for delivery
						
						if ( in_buffer.hasRemaining()){
							
							message = new PooledByteBufferImpl( new DirectByteBuffer( in_buffer.slice()));
							
							forward	= true;
						}
					}
				}
			}
				
			if ( out_buffer != null ){
				
				out_buffer.flip();
				
				connection.send( new PooledByteBufferImpl( new DirectByteBuffer( out_buffer )));
			}
			
			if ( crypto_completed ){
				
				cryptoComplete();
			}
			if ( forward ){
				
				receiveContent( message );
			}
		}catch( Throwable e ){
			
			reportFailed( e );
			
			if ( e instanceof MessageException ){
				
				throw((MessageException)e);
				
			}else{
				
				throw( new MessageException( "Receive failed", e ));
			}
		}
	}

	protected void
	setupBlockCrypto()
	
		throws MessageException
	{
		if ( !failed ){
			
			if ( block_crypto == SESecurityManager.BLOCK_ENCRYPTION_NONE ){
				
				return;
			}
			
			try{
				byte[]	shared_secret = sts_engine.getSharedSecret();
								
			    SecretKeySpec	secret_key_spec1 = new SecretKeySpec(shared_secret, 0, 16, "AES" );
			    SecretKeySpec	secret_key_spec2 = new SecretKeySpec(shared_secret, 8, 16, "AES" );
		        
			    AlgorithmParameterSpec	param_spec1 = 	new IvParameterSpec( AES_IV1);
			    AlgorithmParameterSpec	param_spec2 = 	new IvParameterSpec( AES_IV2);      
			        
			    Cipher cipher1 = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
			    Cipher cipher2 = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
		        
			    if ( connection.isIncoming()){
			    	
			        cipher1.init( Cipher.ENCRYPT_MODE, secret_key_spec1, param_spec1 );
			        cipher2.init( Cipher.DECRYPT_MODE, secret_key_spec2, param_spec2 );
			        
			        incoming_cipher	= cipher2;
			        outgoing_cipher	= cipher1;
			        
			    }else{
			    	
			        cipher1.init( Cipher.DECRYPT_MODE, secret_key_spec1, param_spec1 );
			        cipher2.init( Cipher.ENCRYPT_MODE, secret_key_spec2, param_spec2 );
			        
			        incoming_cipher	= cipher1;
			        outgoing_cipher	= cipher2;
			    }

			}catch( Throwable e ){
				
				throw( new MessageException( "Failed to setup block encryption", e ));
			}
		}
	}

	protected void
	cryptoComplete()
	
		throws MessageException
	{
		crypto_complete.releaseForever();
	}
	
	public void
	send(
		PooledByteBuffer			message )
	
		throws MessageException
	{
		if ( failed ){
			
			throw( new MessageException( "Connection failed" ));
		}
		
		try{
			if ( crypto_complete.isReleasedForever()){
				
				sendContent( message );
				
			}else{
				
					// not complete, stash the message so it has a chance of being piggybacked on
					// the crypto protocol exchange
				
				synchronized( this ){
					
					if ( pending_message == null ){
						
						pending_message = message;
					}
				}
			}
			
			crypto_complete.reserve();
						
				// if the pending message couldn't be piggy backed it'll still be allocated
				
			boolean	send_it = false;
				
			synchronized( this ){

				if ( pending_message == message ){
					
					pending_message	= null;
					
					send_it	= true;
				}
			}
			
			if ( send_it ){
				
				sendContent( message );
			}

		}catch( Throwable e ){
			
			setFailed();
			
			if ( e instanceof MessageException ){
				
				throw((MessageException)e);
				
			}else{
				
				throw( new MessageException( "Send failed", e ));
			}
		}
	}
	
	protected void
	sendContent(
		PooledByteBuffer			message )
	
		throws MessageException
	{
		if ( outgoing_cipher != null ){
			
			try{
				byte[]	plain	=  message.toByteArray();
				byte[]	enc		= outgoing_cipher.doFinal( plain );
			
				PooledByteBuffer	temp = new PooledByteBufferImpl( enc );
				
				try{
					connection.send( temp );
					
						// successfull send -> release caller's buffer
					
					message.returnToPool();
					
				}catch( Throwable e ){
					
						// failed semantics are to not release the caller's buffer
					
					temp.returnToPool();
					
					throw( e );
				}
				
			}catch( Throwable e ){
				
				throw( new MessageException( "Failed to encrypt data", e ));
			}
		}else{
				// sanity check - never allow unencrypted outbound if block enc selected
			
			if ( block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE ){
				
				connection.close();
				
				throw( new MessageException( "Crypto isn't setup" ));
			}
		
			connection.send( message );
		}
	}
	
	protected void
	receiveContent(
		PooledByteBuffer			message )
	
		throws MessageException
	{
		boolean	buffer_handled = false;
		
		try{
			if ( incoming_cipher != null ){
			
				try{
					byte[]	enc 	= message.toByteArray();
					byte[]	plain 	= incoming_cipher.doFinal( enc );
	
					PooledByteBuffer	temp = new PooledByteBufferImpl( plain );
	
					message.returnToPool();
					
					buffer_handled	= true;
					
					message	= temp;
					
				}catch( Throwable e ){
					
					throw( new MessageException( "Failed to decrypt data", e ));
				}
				
			}else if ( block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE ){
				
				throw( new MessageException( "Crypto isn't setup" ));
			}
			
			for (int i=0;i<listeners.size();i++){
				
				PooledByteBuffer	message_to_deliver;
				
				if ( i == 0 ){
					
					message_to_deliver	= message;
					
				}else{
				
						// unlikely we'll ever have > 1 receiver....
					
					message_to_deliver = new PooledByteBufferImpl( message.toByteArray());
				}
				
				try{
					((GenericMessageConnectionListener)listeners.get(i)).receive( this, message_to_deliver );
					
					if ( message_to_deliver == message ){
						
						buffer_handled	= true;
					}
				}catch( Throwable e ){
					
					message_to_deliver.returnToPool();
					
					buffer_handled	= true;
					
					Debug.printStackTrace( e );
				}
			}
		}finally{
			
			if ( !buffer_handled ){
				
				message.returnToPool();
			}
		}
	}
	
	public void
	close()
	
		throws MessageException
	{
		connection.close();
	}
	
	protected void
	reportConnected()
	{
			// we've got to take this off the current thread to avoid the connection even causing immediate
			// submission of a message which then block this thread awaiting crypto completion. "this" thread
			// is currently the selector thread which then screws the crypto protocol...
		
		new AEThread( "SESTSConnection:connected", true )
		{
			public void
			runSupport()
			{
				for (int i=0;i<listeners.size();i++){
					
					try{
						((GenericMessageConnectionListener)listeners.get(i)).connected( SESTSConnectionImpl.this );
						
					}catch( Throwable e ){
						
						Debug.printStackTrace( e );
					}
				}
			}
		}.start();
		
	}
	
	protected void
	reportFailed(
		Throwable	error )
	{
		setFailed();
		
		for (int i=0;i<listeners.size();i++){
			
			try{
				((GenericMessageConnectionListener)listeners.get(i)).failed( this, error );
				
			}catch( Throwable e ){
				
				Debug.printStackTrace( e );
			}
		}
	}
	
	public void
	addListener(
		GenericMessageConnectionListener		listener )
	{
		listeners.add( listener );
	}
	
	public void
	removeListener(
		GenericMessageConnectionListener		listener )
	{
		listeners.remove( listener );
	}
}

⌨️ 快捷键说明

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