@@ -21,8 +21,10 @@ import java.io.FileInputStream
2121import java.io.FileOutputStream
2222import java.io.IOException
2323import java.net.InetAddress
24+ import java.nio.ByteBuffer
2425import java.util.logging.Logger
2526import kotlin.concurrent.thread
27+ import kotlin.time.TimeSource
2628
2729const val SERVER_PORT = " ServerPort"
2830const val SERVER_IP = " ServerIP"
@@ -36,6 +38,12 @@ const val START_VPN_ACTION = "StartMoonbounce"
3638class MBAKVpnService : VpnService ()
3739{
3840 val sizeInBits = 32
41+ val maxBatchSize = 250 // bytes
42+ val maxPacketSize = 2048
43+ val timeoutDuration = 250 // milliseconds
44+ var batchBuffer = byteArrayOf()
45+ var lastPacketSentTime = TimeSource .Monotonic .markNow()
46+
3947 val TAG = " MBAKVpnService"
4048 var parcelFileDescriptor: ParcelFileDescriptor ? = null
4149 var transmissionConnection: TransmissionConnection ? = null
@@ -70,7 +78,6 @@ class MBAKVpnService : VpnService()
7078
7179 override fun onStartCommand (intent : Intent ? , flags : Int , startId : Int ): Int
7280 {
73- print (" ****** onStartCommand called *******" )
7481 super .onStartCommand(intent, flags, startId)
7582
7683 if (intent != null )
@@ -108,7 +115,7 @@ class MBAKVpnService : VpnService()
108115 // Otherwise its outgoing packets will be sent back to the VPN interface and cause an infinite loop.
109116 if (this .transmissionConnection == null )
110117 {
111- throw Error (" Failed to create a connection to the server." )
118+ throw Error (" 🌙 Failed to create a connection to the server." )
112119 }
113120
114121 protect(transmissionConnection!! .tcpConnection!! )
@@ -135,7 +142,7 @@ class MBAKVpnService : VpnService()
135142 this .shadowConnection = ShadowConnection (config, Logger .getLogger(" MoonbounceShadowLogger" ), this .transmissionConnection!! )
136143 }
137144
138- println (" 🌙 MBAKVpnService: starting ServerToVPN loop" )
145+ // println("🌙 MBAKVpnService: starting ServerToVPN loop")
139146 thread(start = true )
140147 {
141148 if (this .usePluggableTransport)
@@ -148,7 +155,7 @@ class MBAKVpnService : VpnService()
148155 }
149156 }
150157
151- println (" 🌙 MBAKVpnService: starting VPNtoServer loop" )
158+ // println("🌙 MBAKVpnService: starting VPNtoServer loop")
152159 thread(start = true )
153160 {
154161 if (this .usePluggableTransport)
@@ -161,7 +168,6 @@ class MBAKVpnService : VpnService()
161168 }
162169 }
163170
164- println (" We have successfully created a VPN tunnel." )
165171 // We have successfully created a VPN tunnel
166172 broadcastStatus(vpnStatusNotification, VPN_CONNECTED_STATUS , true )
167173 }
@@ -199,7 +205,11 @@ class MBAKVpnService : VpnService()
199205
200206 fun vpnToServer (vpnInputStream : FileInputStream , serverConnection : Connection )
201207 {
202- var readBuffer = ByteArray (2048 )
208+ val now = TimeSource .Monotonic .markNow()
209+ val packetLengthSize = sizeInBits/ 8 // In bytes
210+ val lengthBuffer = ByteBuffer .allocate(packetLengthSize)
211+ var readBuffer = ByteArray (maxPacketSize)
212+
203213 val numberOfBytesReceived = vpnInputStream.read(readBuffer)
204214
205215 if (numberOfBytesReceived == - 1 )
@@ -214,7 +224,30 @@ class MBAKVpnService : VpnService()
214224 }
215225
216226 readBuffer = readBuffer.dropLast(readBuffer.size - numberOfBytesReceived).toByteArray()
217- serverConnection.writeWithLengthPrefix(readBuffer, sizeInBits)
227+
228+ // / Batching ///
229+ // Create the packet size prefix
230+ lengthBuffer.putInt(numberOfBytesReceived)
231+ // Add the packet size prefix
232+ batchBuffer + = lengthBuffer.array()
233+ // Add the packet payload
234+ batchBuffer + = readBuffer
235+
236+ // If we have enough data, send it
237+ if (batchBuffer.size >= maxBatchSize)
238+ {
239+ serverConnection.write(batchBuffer)
240+
241+ // println("🙀🙀Wrote ${batchBuffer.size} bytes to the server connection.")
242+ batchBuffer = byteArrayOf()
243+ }
244+ else if ((now - lastPacketSentTime).inWholeMilliseconds >= timeoutDuration)
245+ {
246+ serverConnection.write(batchBuffer)
247+
248+ // println("\uD83D\uDE40\uD83D\uDE40 TIMEOUT!! Wrote ${batchBuffer.size} bytes to the server connection.")
249+ batchBuffer = byteArrayOf()
250+ }
218251
219252 return
220253 }
@@ -294,8 +327,6 @@ class MBAKVpnService : VpnService()
294327
295328 val parcelFileDescriptor = builder.establish()
296329
297- println (" 🌙 finished setting up the VPNService builder" )
298-
299330 return parcelFileDescriptor
300331 }
301332
@@ -327,7 +358,6 @@ class MBAKVpnService : VpnService()
327358 }
328359 else
329360 {
330- println (" 🌙 MBAKVpnService: MBAKVpnService intent was null" )
331361 return false
332362 }
333363
@@ -401,7 +431,7 @@ class MBAKVpnService : VpnService()
401431 val notification: Notification = Notification .Builder (this , notificationChannelId)
402432 .setSmallIcon(R .drawable.crecent_moon)
403433 .setContentTitle(" VPN Service Channel" )
404- .setContentText(" VPN Tunnel is ON. Navigate to the MBAK App to turn it off." )
434+ .setContentText(" The VPN Tunnel is ON. Navigate to the VPN App to turn it off." )
405435 .setContentIntent(pendingIntent)
406436 .build()
407437
@@ -424,7 +454,6 @@ class MBAKVpnService : VpnService()
424454
425455 fun cleanup ()
426456 {
427- println (" cleanUp() called." )
428457 try {
429458 parcelFileDescriptor?.close()
430459 } catch (ex: IOException ) {
0 commit comments