This repository has been archived by the owner on Jun 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSession.cs
196 lines (167 loc) · 6.09 KB
/
Session.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using ViciNet.Protocol;
using ViciNet.RequestAttribute;
namespace ViciNet
{
public class Session : IDisposable
{
// A named request message
public const byte CmdRequest = 0;
// An unnamed response message for a request
public const byte CmdResponse = 1;
// An unnamed response if requested command is unknown
public const byte CmdUnknown = 2;
// A named event registration request
public const byte EventRegister = 3;
// A named event de-registration request
public const byte EventUnregister = 4;
// An unnamed response for successful event (de-)registration
public const byte EventConfirm = 5;
// A unnamed response if event (de-)registration failed
public const byte EventUnknown = 6;
// A named event message
public const byte Event = 7;
private readonly Transport _transport;
public Session() : this("/var/run/charon.vici")
{
}
public Session(string path)
{
var endPoint = new UnixEndPoint(path);
_transport = new Transport(endPoint);
}
public Session(Socket socket, EndPoint endPoint)
{
_transport = new Transport(socket, endPoint);
}
private static string PacketType(byte type)
{
switch (type)
{
case 0: return "command-request";
case 1: return "command-response";
case 2: return "event-unknown";
case 3: return "event-register";
case 4: return "event-unregister";
case 5: return "event-confirm";
case 6: return "event-unknown";
case 7: return "event";
default: return "undefined";
}
}
private static Exception PacketTypeException(byte packetType)
{
return new InvalidDataException($"packet-type:{packetType}" + '(' + PacketType(packetType) + ')');
}
private Packet Communicate(Packet packet)
{
_transport.Send(packet);
return _transport.Receive();
}
public Message[] Request(string command, params Message[] messages)
{
var packet = new Packet(CmdRequest, command, messages);
var response = Communicate(packet);
var responseType = response.PacketType;
if (responseType != CmdResponse)
{
throw PacketTypeException(responseType);
}
return response.Messages;
}
private void RegisterEvent(string eventStreamType)
{
RegisterUnregister(eventStreamType, EventRegister);
}
private void UnregisterEvent(string eventStreamType)
{
RegisterUnregister(eventStreamType, EventUnregister);
}
private void RegisterUnregister(string eventStreamType, byte registerType)
{
var packet = new Packet(registerType, eventStreamType);
var response = Communicate(packet);
var packetType = response.PacketType;
switch (packetType)
{
case EventUnknown:
throw PacketTypeException(packetType);
case EventConfirm:
return;
default:
throw PacketTypeException(packetType);
}
}
public Message[][] StreamedRequest(string command, string eventStreamType, params Message[] messages)
{
var messagesList = new List<Message[]>();
var packet = new Packet(CmdRequest, command, messages);
RegisterEvent(eventStreamType);
var sendCode = _transport.Send(packet);
while (true)
{
var response = _transport.Receive();
var packetType = response.PacketType;
var receivedMessages = response.Messages;
switch (packetType)
{
case CmdResponse:
UnregisterEvent(eventStreamType);
messagesList.Add(receivedMessages);
return messagesList.ToArray();
case Event:
messagesList.Add(receivedMessages);
break;
default:
UnregisterEvent(eventStreamType);
throw PacketTypeException(packetType);
}
}
}
public Message[] Request(Command command, params Message[] messages)
{
return Request(command.GetName(), messages);
}
public Message[][] StreamedRequest(Command command, StreamEvent eventStreamType, params Message[] messages)
{
return StreamedRequest(command.GetName(), eventStreamType.GetName(), messages);
}
public Message[][] StreamedRequest(Command command, params Message[] messages)
{
return CommandToEventTable.TryGetValue(command, out var streamEvent)
? StreamedRequest(command, streamEvent, messages)
: throw new ArgumentException($"\"{command.GetName()}\" isn't stream command.");
}
private static readonly Dictionary<Command, StreamEvent> CommandToEventTable = new Dictionary<Command, StreamEvent>
{
{
Command.ListSas,
StreamEvent.ListSa
},
{
Command.ListPolicies,
StreamEvent.ListPolicy
},
{
Command.ListConns,
StreamEvent.ListConn
},
{
Command.ListCerts,
StreamEvent.ListCert
},
{
Command.ListAuthorities,
StreamEvent.ListAuthority
}
};
public void Dispose()
{
_transport.Dispose();
}
}
}