/// <summary> /// Create a new Link from the given url /// </summary> public Link Add(Uri addUrl) { var keys = new Dictionary<string, string> (); var parts = HttpUtility.ParseQueryString (addUrl.Query); foreach (string csname in parts) { foreach (var key in parts.GetValues(csname)) { keys.Add(csname.Substring(2), key); } } if (keys.Count == 0) { DebugLog ("There we no keys in the given URI"); return null; } var hashname = Telehash.Hashname.FromKeys (keys); string keyData; if (!keys.TryGetValue ("1a", out keyData)) { DebugLogEvent ("A valid 1a key was not found"); return null; } byte[] remoteKey = Base32Encoder.Decode (keyData); Link link; if (Links.TryGetValue (hashname, out link)) { // TODO: Update the link? } else { link = new Link (this, hashname, remoteKey); } return link; }
public void Receive(Pipe pipe, Packet packet) { if (pipe == null || packet == null || packet.FullPacket.Length == 0) { DebugLog ("Invalid data sent to Receive"); return; } DebugLog ("Received a packet: " + packet.ToDebugString()); DebugLog ("Head length: " + packet.HeadLength + "\n"); // Process handshakes if (packet.HeadLength == 1) { DebugLog ("Processing a handshake"); var inner = self.Decrypt (packet); if (inner == null) { DebugLog ("There was no inner packet\n"); return; } inner.Parent = packet; DebugLog ("Decrypted"); DebugLog (inner.ToDebugString ()); DebugLog ("HERE"); JToken msgType; bool gotValue = inner.Head.TryGetValue ("type", out msgType); // TODO: Handle other types correctly if (gotValue && msgType.ToString () != "link") { DebugLog ("We can only handle key type messages right now\n"); return; } DebugLog ("Building hashname"); // Get the hashname from the inner packet var keyPacket = Packet.DecodePacket (inner.Body); if (keyPacket == null) { DebugLog ("No key packet was in the handshake"); return; } var hashKeys = new Dictionary<string, string> (); foreach (var entry in keyPacket.Head) { // TODO: Move to the new inner packet syntax hashKeys.Add (entry.Key, entry.Value.ToString ()); } var fromHashname = Telehash.Hashname.FromKey ("1a", keyPacket.Body, hashKeys); DebugLog ("Incoming hashname: " + fromHashname); Link curLink; if (Links.TryGetValue (fromHashname, out curLink)) { // TODO: Replace an existing link JToken atToken; if (!inner.Head.TryGetValue ("at", out atToken)) { DebugLog ("No at value was found on handshake"); return; } if (curLink.Exchange.At == atToken.Value<uint> ()) { if (!curLink.Handshake (inner)) { DebugLog ("Could not finish handshake"); return; } if (LinkUp != null) { LinkUp (curLink); } DebugLog ("Start using channels?"); } return; } else { // TODO: Method to approve or reject the hashname? Link newLink = new Link (fromHashname); newLink.Mesh = this; if (!newLink.Handshake (inner)) { DebugLog ("Invalid Handshake for Link"); return; } newLink.AddPipe (pipe); // We index both the hashname and the Token for different lookup cases Links.Add (fromHashname, newLink); DebugLog ("Token for new Link is " + Helpers.ToHexSring(newLink.Exchange.Token)); Links.Add (Helpers.ToHexSring(newLink.Exchange.Token), newLink); if (LinkUp != null) { LinkUp (newLink); } } } else if (packet.HeadLength == 0) { byte[] token = packet.Body.Take(16).ToArray(); Link link; if (Links.TryGetValue (Helpers.ToHexSring (token), out link)) { var outer = link.Exchange.Receive (packet); if (outer == null) { DebugLog ("Unable to decrypt a packet"); // TODO: Do we shutdown the link or exchange? Probably not, DoS } DebugLog ("We got a channel packet: " + outer.ToDebugString ()); link.Receive (outer, pipe); } else { DebugLog ("No known link for channel packet token: " + Helpers.ToHexSring (token)); return; } } DebugLog ("We're out\n"); }