Skip to content

Commit

Permalink
Minor changes after verifiying it works both in tests and on the phones
Browse files Browse the repository at this point in the history
  • Loading branch information
compscidr committed Dec 14, 2024
1 parent bc134b9 commit 9c28aeb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@ import android.net.VpnService
import android.os.Binder
import android.os.IBinder
import android.os.ParcelFileDescriptor
import androidx.appcompat.app.ActionBar.DisplayOptions
import androidx.preference.PreferenceManager
import com.jasonernst.icmp.android.IcmpAndroid
import com.jasonernst.kanonproxy.KAnonProxy.Companion.DEFAULT_PORT
import com.jasonernst.kanonproxy.model.KAnonViewModel
import com.jasonernst.kanonproxy.ui.VpnUiService
import com.jasonernst.knet.network.ip.IpType
import com.jasonernst.packetdumper.serverdumper.ConnectedUsersChangedCallback
import com.jasonernst.packetdumper.serverdumper.PcapNgTcpServerPacketDumper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.slf4j.LoggerFactory
import java.net.DatagramSocket
import java.net.Inet4Address
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Socket
import java.nio.channels.DatagramChannel

class KAnonVpnService: VpnService(), VpnUiService, ConnectedUsersChangedCallback, VpnProtector {
private val logger = LoggerFactory.getLogger(javaClass)
Expand Down Expand Up @@ -64,19 +72,24 @@ class KAnonVpnService: VpnService(), VpnUiService, ConnectedUsersChangedCallback

vpnFileDescriptor = builder.establish() ?: throw RuntimeException("Error establishing VPN")

//val onlyDestination = listOf(InetAddress.getByName("8.8.8.8"))
val onlyDestination = emptyList<InetAddress>()
// val onlyProtocols = listOf(IpType.UDP.value)
val onlyProtocols = emptyList<UByte>()
client = AndroidClient(vpnFileDescriptor = vpnFileDescriptor, packetDumper = packetDumper, onlyDestinations = onlyDestination, onlyProtocols = onlyProtocols)
client.connect()
viewModel.serviceStarted()
CoroutineScope(Dispatchers.IO).launch {
// val onlyDestination = listOf(InetAddress.getByName("8.8.8.8"), InetAddress.getByName("8.8.4.4"))
val onlyDestination = emptyList<InetAddress>()
// val onlyProtocols = listOf(IpType.UDP.value)
val onlyProtocols = emptyList<UByte>()
val datagramChannel = DatagramChannel.open()
datagramChannel.configureBlocking(false)
datagramChannel.connect(InetSocketAddress("127.0.0.1", DEFAULT_PORT))
client = AndroidClient(vpnFileDescriptor = vpnFileDescriptor, packetDumper = packetDumper, onlyDestinations = onlyDestination, onlyProtocols = onlyProtocols, datagramChannel = datagramChannel)
client.start()
viewModel.serviceStarted()
}
}

override fun stopVPN() {
vpnFileDescriptor.close()
server.stop()
client.close()
client.stop()
viewModel.serviceStopped()
}

Expand Down
6 changes: 3 additions & 3 deletions client/src/main/kotlin/com/jasonernst/kanonproxy/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ abstract class Client(
for (changeRequest in changeRequests) {
when (changeRequest.type) {
REGISTER -> {
logger.debug("Processing REGISTER: ${changeRequest.ops}")
// logger.debug("Processing REGISTER: ${changeRequest.ops}")
changeRequest.channel.register(selector, changeRequest.ops)
}
CHANGE_OPS -> {
logger.debug("Processing CHANGE_OPS: ${changeRequest.ops}")
// logger.debug("Processing CHANGE_OPS: ${changeRequest.ops}")
val key = changeRequest.channel.keyFor(selector)
key.interestOps(changeRequest.ops)
}
Expand Down Expand Up @@ -229,7 +229,7 @@ abstract class Client(
}
}
if (numPackets > 0) {
logger.debug("Added packets, switching to WRITE mode")
// logger.debug("Added packets, switching to WRITE mode")
synchronized(changeRequests) {
changeRequests.add(ChangeRequest(datagramChannel, CHANGE_OPS, OP_WRITE))
}
Expand Down
37 changes: 29 additions & 8 deletions core/src/main/kotlin/com/jasonernst/kanonproxy/Session.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import java.nio.ByteBuffer
import java.nio.channels.ByteChannel
import java.nio.channels.CancelledKeyException
import java.nio.channels.ClosedSelectorException
import java.nio.channels.DatagramChannel
import java.nio.channels.SelectionKey
import java.nio.channels.SelectionKey.OP_CONNECT
import java.nio.channels.Selector
Expand Down Expand Up @@ -231,15 +230,16 @@ abstract class Session(
try {
val selectedKeys = selector.selectedKeys()
if (selectedKeys.size > 0) {
logger.warn("SELECT: $selectedKeys")
// logger.warn("SELECT: ${selectedKeys.toString()}")
}
val keyStream = selectedKeys.parallelStream()
keyStream
.forEach {
if (!it.isValid) {
logger.error("INVALID KEY!!!!! $this@Session")
logger.error("INVALID KEY!!! ${keyToString(it)}")
}
if (it.isWritable && it.isValid) {
logger.debug("WRITABLE KEY: ${keyToString(it)}")
// could do a while loop here, but others might starve
if (outgoingQueue.isNotEmpty()) {
val queue = outgoingQueue.take()
Expand All @@ -257,20 +257,18 @@ abstract class Session(
}
}
if (it.isReadable && it.isValid) {
// logger.warn("READABLE!!!!")
logger.debug("READABLE KEY: ${keyToString(it)}")
if (!read()) {
logger.warn("Remote read failed, closing selector")
it.interestOps(0)
selector.close()
}
}
if (it.isConnectable && it.isValid) {
if (it.channel() is DatagramChannel) {
logger.warn("IN CONNECTABLE AS DATAGRAM CHANNEL")
}
// AFAIK its only possible to be here if its a SocketChannel
val socketChannel = it.channel() as SocketChannel
// logger.debug("Tcp connectable, trying to finish connection to ${socketChannel.remoteAddress}")
if (socketChannel.isConnectionPending) {
logger.debug("CONNECTING PENDING KEY: ${keyToString(it)}")
try {
val result = socketChannel.finishConnect()
if (result) {
Expand Down Expand Up @@ -497,4 +495,27 @@ abstract class Session(
logger.warn("Failed to close channel")
}
}

/**
* Helper function to print useful info from a selector
*/
fun keyToString(selectionKey: SelectionKey): String {
val sb = StringBuilder()
sb
.append("channel=")
.append(selectionKey.channel())
.append(", selector=")
.append(selector)
if (selectionKey.isValid) {
sb
.append(", interestOps=")
.append(selectionKey.interestOps())
.append(", readyOps=")
.append(selectionKey.readyOps())
} else {
sb.append(", invalid")
}

return sb.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class AnonymousTcpSession(
// that connect will take care of it. If it doesn't we can fall back to open with the InetSocketAddress, however,
// that will do connect during open.
override var channel: SocketChannel = SocketChannel.open()
var connectTime: Long = 0L
var connectTime: Long = System.currentTimeMillis()

override fun handleReturnTrafficLoop(maxRead: Int): Int {
val len = super.handleReturnTrafficLoop(maxRead)
Expand Down Expand Up @@ -79,9 +79,9 @@ class AnonymousTcpSession(
init {
channel.socket().keepAlive = false
channel.configureBlocking(false)

startSelector()
protector.protectTCPSocket(channel.socket())
startSelector()
Thread.yield()
tcpStateMachine.passiveOpen()
outgoingScope.launch {
if (isRunning.get().not()) {
Expand All @@ -100,8 +100,7 @@ class AnonymousTcpSession(
private fun connect() {
try {
logger.debug("TCP connecting to {}:{}", initialIpHeader!!.destinationAddress, initialTransportHeader!!.destinationPort)
connectTime = System.currentTimeMillis()
logger.debug("Adding REGISTER request to CONNECT")
// logger.debug("Adding REGISTER request to CONNECT")
val result =
channel.connect(
InetSocketAddress(initialIpHeader!!.destinationAddress, initialTransportHeader!!.destinationPort.toInt()),
Expand All @@ -128,7 +127,7 @@ class AnonymousTcpSession(
}
} else {
logger.debug("CONNECT called, waiting for selector")
channel.finishConnect()
// channel.finishConnect() // this makes haywire select messages show up.
}
selector.wakeup()
} catch (e: Exception) {
Expand Down

0 comments on commit 9c28aeb

Please sign in to comment.