public void connect(InetSocketAddress destAddress) { if (VpnServiceHelper.protect(mInnerChannel.Socket())) { mDestAddress = destAddress; mInnerChannel.Register(mSelector, Operations.Connect, this); mInnerChannel.Connect(mServerEP); Debug.WriteLine($"Connecting to {mServerEP}"); } else { throw new Exception("VPN protect socket failed."); } }
private void InitializeConnection(Java.Lang.String ipAndPort, InetAddress destinationAddress, int destinationPort, Packet currentPacket, TCPHeader tcpHeader, ByteBuffer responseBuffer) { currentPacket.SwapSourceAndDestination(); if (tcpHeader.isSYN()) { SocketChannel outputChannel = SocketChannel.Open(); outputChannel.ConfigureBlocking(false); vpnService.Protect(outputChannel.Socket()); TCB tcb = new TCB(ipAndPort, random.NextInt(Short.MaxValue + 1), tcpHeader.sequenceNumber, tcpHeader.sequenceNumber + 1, tcpHeader.acknowledgementNumber, outputChannel, currentPacket); TCB.PutTCB(ipAndPort, tcb); try { outputChannel.Connect(new InetSocketAddress(destinationAddress, destinationPort)); if (outputChannel.FinishConnect()) { tcb.status = TCB.TCBStatus.SYN_RECEIVED; // TODO: Set MSS for receiving larger packets from the device currentPacket.updateTCPBuffer(responseBuffer, (byte)(TCPHeader.SYN | TCPHeader.ACK), tcb.mySequenceNum, tcb.myAcknowledgementNum, 0); tcb.mySequenceNum++; // SYN counts as a byte } else { tcb.status = TCB.TCBStatus.SYN_SENT; selector.Wakeup(); tcb.selectionKey = outputChannel.Register(selector, SelectionKey.OpConnect, tcb); return; } } catch (IOException e) { Log.Error(TAG, "Connection error: " + ipAndPort, e); currentPacket.updateTCPBuffer(responseBuffer, (byte)TCPHeader.RST, 0, tcb.myAcknowledgementNum, 0); TCB.CloseTCB(tcb); } } else { currentPacket.updateTCPBuffer(responseBuffer, (byte)TCPHeader.RST, 0, tcpHeader.sequenceNumber + 1, 0); } outputQueue.Offer(responseBuffer); }
internal SocketChannel AcceptServerSideChannel(SocketChannel localServer) { var promise = new TaskCompletionSource <Socket>(); var task = promise.Task; localServer.Socket.Listen(100); localServer.Socket.BeginAccept(ar => promise.SetResult(localServer.Socket.EndAccept(ar)), null); Selector.Send(ConnectionActor, SelectionHandler.ChannelConnectable.Instance); task.Wait(); var channel = new SocketChannel(task.Result); channel.Register(ChannelProbe, SocketAsyncOperation.None); return(channel); }
public void Register(SocketChannel channel, SocketAsyncOperation?initialOps, IActorRef channelActor) { channel.Register(channelActor, initialOps); RegisterCallReceiver.Ref.Tell(new TcpConnectionSpec.Registration(channel, initialOps)); }
private void processACK(TCB tcb, TCPHeader tcpHeader, ByteBuffer payloadBuffer, ByteBuffer responseBuffer) { try { int payloadSize = payloadBuffer.Limit() - payloadBuffer.Position(); lock (tcb) { SocketChannel outputChannel = tcb.channel; if (tcb.status == TCB.TCBStatus.SYN_RECEIVED) { tcb.status = TCB.TCBStatus.ESTABLISHED; selector.Wakeup(); tcb.selectionKey = outputChannel.Register(selector, SelectionKey.OpRead, tcb); tcb.waitingForNetworkData = true; } else if (tcb.status == TCB.TCBStatus.LAST_ACK) { CloseCleanly(tcb, responseBuffer); return; } if (payloadSize == 0) { return; // Empty ACK, ignore } if (!tcb.waitingForNetworkData) { selector.Wakeup(); // tcb.selectionKey.InterestOps(SelectionKey.OpRead); tcb.selectionKey.InterestOps(); tcb.waitingForNetworkData = true; } // Forward to remote server try { while (payloadBuffer.HasRemaining) { outputChannel.Write(payloadBuffer); } } catch (IOException e) { Log.Error(TAG, "Network write error: " + tcb.ipAndPort, e); SendRST(tcb, payloadSize, responseBuffer); return; } // TODO: We don't expect out-of-order packets, but verify tcb.myAcknowledgementNum = tcpHeader.sequenceNumber + payloadSize; tcb.theirAcknowledgementNum = tcpHeader.acknowledgementNumber; Packet referencePacket = tcb.referencePacket; referencePacket.updateTCPBuffer(responseBuffer, (byte)TCPHeader.ACK, tcb.mySequenceNum, tcb.myAcknowledgementNum, 0); } outputQueue.Offer(responseBuffer); } catch (Exception ex) { System.Console.WriteLine(ex.Message); } }