├── XamarinAndroidVPNExample
├── Resources
│ ├── values
│ │ ├── dimens.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── Strings.xml
│ │ ├── colors.xml
│ │ └── styles.xml
│ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ ├── layout
│ │ └── activity_main.axml
│ └── AboutResources.txt
├── Assets
│ └── AboutAssets.txt
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
├── VPNService
│ ├── LRUCache.cs
│ ├── ByteBufferPool.cs
│ ├── UDPInput.cs
│ ├── TCB.cs
│ ├── UDPOutput.cs
│ ├── TCPInput.cs
│ ├── LocalVPNService.cs
│ ├── TCPOutput.cs
│ └── Packet.cs
├── packages.config
├── MainActivity.cs
└── XamarinAndroidVPNExample.csproj
├── XamarinAndroidVPNExample.sln
├── .gitattributes
└── .gitignore
/XamarinAndroidVPNExample/Resources/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
4 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2C3E50
4 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/values/Strings.xml:
--------------------------------------------------------------------------------
1 |
2 | XamarinAndroidVPNExample
3 | Settings
4 |
5 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manicoder/XamarinAndroidVPNExample/HEAD/XamarinAndroidVPNExample/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2c3e50
4 | #1B3147
5 | #3498db
6 |
7 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/layout/activity_main.axml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Assets/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "AndroidAsset".
3 |
4 | These files will be deployed with you package and will be accessible using Android's
5 | AssetManager, like this:
6 |
7 | public class ReadAsset : Activity
8 | {
9 | protected override void OnCreate (Bundle bundle)
10 | {
11 | base.OnCreate (bundle);
12 |
13 | InputStream input = Assets.Open ("my_asset.txt");
14 | }
15 | }
16 |
17 | Additionally, some Android functions will automatically load asset files:
18 |
19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/VPNService/LRUCache.cs:
--------------------------------------------------------------------------------
1 | using Java.Util;
2 |
3 | namespace XamarinAndroidVPNExample.VPNService
4 | {
5 | public abstract class LRUCache : LinkedHashMap
6 | {
7 | private int maxSize;
8 |
9 | public LRUCache(int maxSize)
10 | : base(maxSize + 1, 1, true)
11 | {
12 | this.maxSize = maxSize;
13 | }
14 |
15 | protected override bool RemoveEldestEntry(IMapEntry eldest)
16 | {
17 | if (this.Size() > maxSize)
18 | {
19 | Cleanup(eldest);
20 | return true;
21 | }
22 |
23 | return false;
24 | }
25 |
26 | public virtual void Cleanup(IMapEntry eldest)
27 | {
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/VPNService/ByteBufferPool.cs:
--------------------------------------------------------------------------------
1 | using Java.Nio;
2 | using Java.Util.Concurrent;
3 |
4 | namespace XamarinAndroidVPNExample.VPNService
5 | {
6 | public class ByteBufferPool: Java.Lang.Object
7 | {
8 | private const int BUFFER_SIZE = 16384; // XXX: Is this ideal?
9 | private static ConcurrentLinkedQueue pool = new ConcurrentLinkedQueue();
10 |
11 | public static ByteBuffer acquire()
12 | {
13 | var buffer = (ByteBuffer)pool.Poll();
14 | if (buffer == null)
15 | buffer = ByteBuffer.AllocateDirect(BUFFER_SIZE); // Using DirectBuffer for zero-copy
16 | return buffer;
17 | }
18 |
19 | public static void Release(ByteBuffer buffer)
20 | {
21 | buffer.Clear();
22 | pool.Offer(buffer);
23 | }
24 |
25 | public static void Clear()
26 | {
27 | pool.Clear();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("XamarinAndroidVPNExample")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("XamarinAndroidVPNExample")]
14 | [assembly: AssemblyCopyright("Copyright © 2018")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Build and Revision Numbers
27 | // by using the '*' as shown below:
28 | // [assembly: AssemblyVersion("1.0.*")]
29 | [assembly: AssemblyVersion("1.0.0.0")]
30 | [assembly: AssemblyFileVersion("1.0.0.0")]
31 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.438
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamarinAndroidVPNExample", "XamarinAndroidVPNExample\XamarinAndroidVPNExample.csproj", "{3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
17 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {3BC0AC7E-3B3B-4D3F-9CC0-B2BDECC460A6}.Release|Any CPU.Deploy.0 = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(SolutionProperties) = preSolution
22 | HideSolutionNode = FALSE
23 | EndGlobalSection
24 | GlobalSection(ExtensibilityGlobals) = postSolution
25 | SolutionGuid = {22A2A42F-428B-424F-9885-87E76F6C0996}
26 | EndGlobalSection
27 | EndGlobal
28 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.axml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable/
12 | icon.png
13 |
14 | layout/
15 | main.axml
16 |
17 | values/
18 | strings.xml
19 |
20 | In order to get the build system to recognize Android resources, set the build action to
21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
22 | instead operate on resource IDs. When you compile an Android application that uses resources,
23 | the build system will package the resources for distribution and generate a class called "R"
24 | (this is an Android convention) that contains the tokens for each one of the resources
25 | included. For example, for the above Resources layout, this is what the R class would expose:
26 |
27 | public class R {
28 | public class drawable {
29 | public const int icon = 0x123;
30 | }
31 |
32 | public class layout {
33 | public const int main = 0x456;
34 | }
35 |
36 | public class strings {
37 | public const int first_string = 0xabc;
38 | public const int second_string = 0xbcd;
39 | }
40 | }
41 |
42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first
44 | string in the dictionary file values/strings.xml.
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/VPNService/UDPInput.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using Android.Util;
6 | using Java.IO;
7 | using Java.Lang;
8 | using Java.Nio;
9 | using Java.Nio.Channels;
10 | using Java.Util.Concurrent;
11 |
12 | namespace XamarinAndroidVPNExample.VPNService
13 | {
14 | public class UDPInput : Java.Lang.Object, Java.Lang.IRunnable
15 | {
16 | private const string TAG = "UDPInput";
17 | private const int HEADER_SIZE = Packet.IP4_HEADER_SIZE + Packet.UDP_HEADER_SIZE;
18 |
19 | private Selector selector;
20 | private ConcurrentLinkedQueue outputQueue;
21 |
22 | public UDPInput(ConcurrentLinkedQueue outputQueue, Selector selector)
23 | {
24 | this.outputQueue = outputQueue;
25 | this.selector = selector;
26 | }
27 |
28 | public void Run()
29 | {
30 | try
31 | {
32 | Log.Info(TAG, "Started");
33 | while (!Thread.Interrupted())
34 | {
35 | int readyChannels = selector.Select();
36 |
37 | if (readyChannels == 0)
38 | {
39 | Thread.Sleep(10);
40 | continue;
41 | }
42 |
43 | System.Console.WriteLine("UDP In");
44 |
45 | var keys = selector.SelectedKeys().ToList();
46 |
47 | foreach(var key in keys)
48 | {
49 | if (!Thread.Interrupted())
50 | {
51 | if (key.IsValid && key.IsReadable)
52 | {
53 | selector.SelectedKeys().Remove(key);
54 |
55 | ByteBuffer receiveBuffer = ByteBufferPool.acquire();
56 | // Leave space for the header
57 | receiveBuffer.Position(HEADER_SIZE);
58 |
59 | DatagramChannel inputChannel = (DatagramChannel)key.Channel();
60 | // XXX: We should handle any IOExceptions here immediately,
61 | // but that probably won't happen with UDP
62 | int readBytes = inputChannel.Read(receiveBuffer);
63 |
64 | Packet referencePacket = (Packet)key.Attachment();
65 | referencePacket.updateUDPBuffer(receiveBuffer, readBytes);
66 | receiveBuffer.Position(HEADER_SIZE + readBytes);
67 |
68 | outputQueue.Offer(receiveBuffer);
69 | }
70 | }
71 | }
72 | }
73 | }
74 | catch (InterruptedException e)
75 | {
76 | Log.Info(TAG, "Stopping");
77 | }
78 | catch (IOException e)
79 | {
80 | Log.Warn(TAG, e.ToString(), e);
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/VPNService/TCB.cs:
--------------------------------------------------------------------------------
1 | using Java.IO;
2 | using Java.Lang;
3 | using Java.Nio.Channels;
4 | using Java.Util;
5 | using System.Collections.Generic;
6 |
7 | namespace XamarinAndroidVPNExample.VPNService
8 | {
9 | public class TCB : Object
10 | {
11 | public String ipAndPort;
12 |
13 | public long mySequenceNum, theirSequenceNum;
14 | public long myAcknowledgementNum, theirAcknowledgementNum;
15 | public TCBStatus status;
16 |
17 | // TCP has more states, but we need only these
18 | public enum TCBStatus
19 | {
20 | SYN_SENT,
21 | SYN_RECEIVED,
22 | ESTABLISHED,
23 | CLOSE_WAIT,
24 | LAST_ACK,
25 | }
26 |
27 | public Packet referencePacket;
28 |
29 | public SocketChannel channel;
30 | public bool waitingForNetworkData;
31 | public SelectionKey selectionKey;
32 |
33 | private const int MAX_CACHE_SIZE = 50; // XXX: Is this ideal?
34 |
35 | private static TCBLRUCache tcbCache = new TCBLRUCache(MAX_CACHE_SIZE);
36 |
37 | public static TCB GetTCB(String ipAndPort)
38 | {
39 | lock (tcbCache)
40 | {
41 | return (TCB)tcbCache.Get(ipAndPort);
42 | }
43 | }
44 |
45 | public static void PutTCB(String ipAndPort, TCB tcb)
46 | {
47 | lock (tcbCache)
48 | {
49 | tcbCache.Put(ipAndPort, tcb);
50 | }
51 | }
52 |
53 | public TCB(String ipAndPort, long mySequenceNum, long theirSequenceNum, long myAcknowledgementNum, long theirAcknowledgementNum,
54 | SocketChannel channel, Packet referencePacket)
55 | {
56 | this.ipAndPort = ipAndPort;
57 |
58 | this.mySequenceNum = mySequenceNum;
59 | this.theirSequenceNum = theirSequenceNum;
60 | this.myAcknowledgementNum = myAcknowledgementNum;
61 | this.theirAcknowledgementNum = theirAcknowledgementNum;
62 |
63 | this.channel = channel;
64 | this.referencePacket = referencePacket;
65 | }
66 |
67 | public static void CloseTCB(TCB tcb)
68 | {
69 | tcb.CloseChannel();
70 | lock (tcbCache)
71 | {
72 | tcbCache.Remove(tcb.ipAndPort);
73 | }
74 | }
75 |
76 | public static void CloseAll()
77 | {
78 | lock (tcbCache)
79 | {
80 | var it = tcbCache.EntrySet().GetEnumerator();
81 | while (it.MoveNext())
82 | {
83 | try
84 | {
85 | var tcb = (TCB)((IMapEntry)it.Current).Value;
86 | tcb.CloseChannel();
87 | tcbCache.Remove(tcb);
88 | }
89 | catch { }
90 | }
91 | }
92 | }
93 |
94 | private void CloseChannel()
95 | {
96 | try
97 | {
98 | channel.Close();
99 | }
100 | catch (IOException e)
101 | {
102 | // Ignore
103 | }
104 | }
105 |
106 | public class TCBLRUCache : LRUCache
107 | {
108 | public TCBLRUCache(int maxSize) : base(maxSize)
109 | {
110 | }
111 |
112 | public override void Cleanup(IMapEntry eldest)
113 | {
114 | ((TCB)eldest).CloseChannel();
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/XamarinAndroidVPNExample/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Android.App;
3 | using Android.Content;
4 | using Android.Net;
5 | using Android.OS;
6 | using Android.Runtime;
7 | using Android.Support.V4.Content;
8 | using Android.Support.V7.App;
9 | using Android.Views;
10 | using Android.Widget;
11 | using XamarinAndroidVPNExample.VPNService;
12 |
13 | namespace XamarinAndroidVPNExample
14 | {
15 | [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
16 | public class MainActivity : AppCompatActivity
17 | {
18 | private const int VPN_REQUEST_CODE = 0x0F;
19 |
20 | private bool _waitingForVPNStart;
21 |
22 | VpnStateReceiver vpnStateReceiver;
23 |
24 | public class VpnStateReceiver : BroadcastReceiver
25 | {
26 | MainActivity c;
27 |
28 | public VpnStateReceiver(MainActivity c)
29 | {
30 | this.c = c;
31 | }
32 |
33 | public Action Receive { get; set; }
34 |
35 | public override void OnReceive(Context context, Intent intent)
36 | {
37 | if (LocalVPNService.BROADCAST_VPN_STATE.Equals(intent.Action))
38 | {
39 | if (intent.GetBooleanExtra("running", false))
40 | {
41 | c._waitingForVPNStart = false;
42 | }
43 | }
44 | }
45 | }
46 |
47 | protected override void OnCreate(Bundle savedInstanceState)
48 | {
49 | base.OnCreate(savedInstanceState);
50 | SetContentView(Resource.Layout.activity_main);
51 |
52 | Button btStart = FindViewById