Hush – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Threading;
3 using System.Threading.Tasks;
4 using Open.Nat;
5  
6 namespace Hush.Discovery
7 {
8 public class Discovery : IDisposable
9 {
10 public delegate void PortMapFailed(object sender, DiscoveryFailedEventArgs args);
11  
12 public Discovery()
13 {
14 NatDiscoverer = new NatDiscoverer();
15 }
16  
17 public Discovery(string mappingName, CancellationTokenSource cancellationTokenSource,
18 TaskScheduler taskScheduler) : this()
19 {
20 MappingName = mappingName;
21 CancellationTokenSource = cancellationTokenSource;
22 TaskScheduler = taskScheduler;
23 }
24  
25 private static string MappingName { get; set; }
26 private static CancellationTokenSource CancellationTokenSource { get; set; }
27 private static NatDiscoverer NatDiscoverer { get; set; }
28 private static TaskScheduler TaskScheduler { get; set; }
29  
30 private static CancellationTokenSource UpnPCancellationTokenSource { get; set; }
31 private static CancellationTokenSource PmpCancellationTokenSource { get; set; }
32  
33 public void Dispose()
34 {
35 PmpCancellationTokenSource?.Dispose();
36 PmpCancellationTokenSource = null;
37  
38 PmpCancellationTokenSource?.Dispose();
39 PmpCancellationTokenSource = null;
40 }
41  
42 public event PortMapFailed OnPortMapFailed;
43  
44 public async Task<bool> CreateMapping(DiscoveryType type, int port)
45 {
46 switch (type)
47 {
48 case DiscoveryType.Upnp:
49 return await CreateUpnPMapping(port);
50 case DiscoveryType.Pmp:
51 return await CreatePmpPortMapping(port);
52 default:
53 throw new ArgumentException("Unknown discovery type");
54 }
55 }
56  
57 public async Task<bool> DeleteMapping(DiscoveryType type, int port)
58 {
59 switch (type)
60 {
61 case DiscoveryType.Upnp:
62 return await DeleteUpnPMapping(port);
63 case DiscoveryType.Pmp:
64 return await DeletePmpPortMapping(port);
65 default:
66 throw new ArgumentException("Unknown discovery type");
67 }
68 }
69  
70 private async Task<bool> DeleteUpnPMapping(int port)
71 {
72 try
73 {
74 UpnPCancellationTokenSource = new CancellationTokenSource();
75 var linkedCancellationTokenSource =
76 CancellationTokenSource.CreateLinkedTokenSource(UpnPCancellationTokenSource.Token,
77 CancellationTokenSource.Token);
78 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, linkedCancellationTokenSource);
79 await device.DeletePortMapAsync(new Mapping(Protocol.Tcp, port, port, MappingName));
80  
81 return true;
82 }
83 catch
84 {
85 return false;
86 }
87 }
88  
89 private async Task<bool> CreateUpnPMapping(int port)
90 {
91 try
92 {
93 UpnPCancellationTokenSource = new CancellationTokenSource();
94 var linkedCancellationTokenSource =
95 CancellationTokenSource.CreateLinkedTokenSource(UpnPCancellationTokenSource.Token,
96 CancellationTokenSource.Token);
97 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, linkedCancellationTokenSource);
98 await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, MappingName));
99  
100 return true;
101 }
102 catch (Exception ex)
103 {
104 await Task.Delay(0, CancellationTokenSource.Token).ContinueWith(_ =>
105 OnPortMapFailed?.Invoke(this, new DiscoveryFailedEventArgs(DiscoveryType.Upnp, ex)),
106 CancellationTokenSource.Token, TaskContinuationOptions.None, TaskScheduler);
107  
108 return false;
109 }
110 }
111  
112 private async Task<bool> DeletePmpPortMapping(int port)
113 {
114 try
115 {
116 PmpCancellationTokenSource = new CancellationTokenSource();
117 var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(
118 PmpCancellationTokenSource.Token,
119 CancellationTokenSource.Token);
120 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Pmp, linkedCancellationTokenSource);
121 await device.DeletePortMapAsync(new Mapping(Protocol.Tcp, port, port, MappingName));
122 return true;
123 }
124 catch
125 {
126 return false;
127 }
128 }
129  
130 private async Task<bool> CreatePmpPortMapping(int port)
131 {
132 try
133 {
134 PmpCancellationTokenSource = new CancellationTokenSource();
135 var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(
136 PmpCancellationTokenSource.Token,
137 CancellationTokenSource.Token);
138 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Pmp, linkedCancellationTokenSource);
139 await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, MappingName));
140 return true;
141 }
142 catch (Exception ex)
143 {
144 await Task.Delay(0, CancellationTokenSource.Token).ContinueWith(_ =>
145 OnPortMapFailed?.Invoke(this, new DiscoveryFailedEventArgs(DiscoveryType.Pmp, ex)),
146 CancellationTokenSource.Token, TaskContinuationOptions.None, TaskScheduler);
147  
148 return false;
149 }
150 }
151 }
152 }