private void reload_leave_inbound(ReloadMessage recmsg) { LeaveReqAns req_answ = (LeaveReqAns)recmsg.reload_message_body; NodeId OriginatorID = recmsg.OriginatorID; if (req_answ.RELOAD_MsgCode == RELOAD_MessageCode.Leave_Request) { // Leaving nodes will be stored for 2 minutes to make sure we do not learn about them again m_topology.routing_table.AddLeavingNode(req_answ.LeavingNode); m_topology.InboundLeave(req_answ.LeavingNode); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Leave_Answer.ToString().PadRight(16, ' '), OriginatorID, recmsg.TransactionID)); ReloadMessage sendmsg = create_leave_answ(new Destination(OriginatorID), recmsg.TransactionID); recmsg.PutViaListToDestination(sendmsg); send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else { } }
public ReloadMessage create_reload_message(ReloadMessage reloadRequest) { try { reloadRequest.PutViaListToDestination(); } catch (Exception ex) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, "create_reload_message: " + ex.Message); } return reloadRequest; }
/// <summary> /// Handles incoming fetch requests /// </summary> /// <param name="recmsg"></param> private void reload_fetch_inbound(ReloadMessage recmsg) { ReloadMessage sendmsg; if (recmsg.IsRequest()) { FetchReq fetchRequest = (FetchReq)recmsg.reload_message_body; NodeId originatorId = recmsg.OriginatorID; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Fetch_Answer.ToString().PadRight(16, ' '), originatorId, recmsg.TransactionID)); // List of SignerIdentities of the data to be fetched List<SignerIdentity> signers = new List<SignerIdentity>(); var fetchKindResponses = new List<FetchKindResponse>(); foreach (StoredDataSpecifier specifier in fetchRequest.Specifiers) { FetchKindResponse fetchKindResponse; if (m_topology.Fetch(fetchRequest.ResourceId, specifier, out fetchKindResponse)) { fetchKindResponses.Add(fetchKindResponse); // add certificate foreach (StoredData data in fetchKindResponse.values) if (!signers.Contains(data.Signature.Identity)) signers.Add(data.Signature.Identity); } else { sendmsg = create_erro_reply(new Destination(originatorId), RELOAD_ErrorCode.Error_Not_Found, "Topology: RessourceId not found", recmsg.TransactionID); recmsg.PutViaListToDestination(sendmsg); send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); return; } } sendmsg = create_fetch_answ(new Destination(originatorId), recmsg.TransactionID, fetchKindResponses); // get certificates for this data List<GenericCertificate> certs = new List<GenericCertificate>(); certs.AddRange(m_ReloadConfig.AccessController.GetPKCs(signers)); // add certificates to fetch answer sendmsg.security_block.Certificates.AddRange(certs); recmsg.PutViaListToDestination(sendmsg); //sendmsg.addOverlayForwardingOptions(recmsg); //Proprietary //--Joscha if (m_machine is GWMachine) { //workaround in case date is stored at the gateway node responsible to route the message back into the interconnectionoverlay if (sendmsg.forwarding_header.destination_list[0].destination_data.node_id == ((GWMachine)m_machine).GateWay.interDomainPeer.Topology.LocalNode.Id) { sendmsg.reload_message_body.RELOAD_MsgCode = RELOAD_MessageCode.Fetch_Answer; ((GWMachine)m_machine).GateWay.interDomainPeer.Inject(sendmsg); //TODO: change other cases } else send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else { // It is a FetchAns, no reply needed } }
private void reload_ping_inbound(ReloadMessage recmsg) { PingReqAns req_answ = (PingReqAns)recmsg.reload_message_body; NodeId originatorID = recmsg.OriginatorID; if (recmsg.IsRequest()) { // is still my Finger? /* Topology.RoutingTable.FTableEntry ftEntry; if (m_topology.routing_table.isFinger(originatorID, out ftEntry)) { if (m_topology.routing_table.IsAttached(originatorID)) Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Topology.RoutingTable.FTableEntry, ReloadMessage>( ftEntry, recmsg, AttachFinger)); } */ m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Ping_Answer.ToString().PadRight(16, ' '), originatorID, recmsg.TransactionID)); ReloadMessage sendmsg = create_ping_answ(new Destination(originatorID), recmsg.TransactionID); recmsg.PutViaListToDestination(sendmsg); send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else { } }
/// <summary> /// Handles incoming StoreReq messages. /// </summary> /// <param name="recmg">The received RELOAD message</param> private void reload_store_inbound(ReloadMessage recmsg) { if (recmsg.IsRequest()) { StoreReq storeRequest = (StoreReq)recmsg.reload_message_body; NodeId originatorID = recmsg.OriginatorID; List<StoreKindData> recStoreKindData; // TODO: For now add certificate to global PKC Store, but they are only temporarilly needed in validateDataSignature m_ReloadConfig.AccessController.SetPKCs(recmsg.security_block.Certificates); Boolean validRequest = true; recStoreKindData = storeRequest.StoreKindData; // validate data signature foreach (StoreKindData store_kind in recStoreKindData) { foreach (StoredData sd in store_kind.Values) { if (!m_ReloadConfig.AccessController.validateDataSignature(storeRequest.ResourceId, store_kind.Kind, sd)) { validRequest = false; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "DATA SIGNATURE INVALID!! Store Failed!!"); } } } if (storeRequest.Replica_number == 1) { // find sender in my predecessors int sender = m_topology.routing_table.Predecessors.IndexOf(recmsg.OriginatorID); // sender not in my predecessors if (sender < 0) validRequest = false; // we are able to perform validity checks if (m_topology.routing_table.Predecessors.Count > 2) { if (!storeRequest.ResourceId.ElementOfInterval(m_topology.routing_table.Predecessors[sender + 1], m_topology.routing_table.Predecessors[sender], true)) // is the storing peer responsible for that resourceId? validRequest = false; } } // REPLICATEST if (validRequest) { if (storeRequest.Replica_number == 1) { if (!m_topology.Replicas.Contains(storeRequest.ResourceId.ToString())) { m_topology.Replicas.Add(storeRequest.ResourceId.ToString()); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("Add Ressource {0} as Replica", storeRequest.ResourceId.ToString())); } } if (storeRequest.Replica_number == 0 && m_topology.Replicas.Contains(storeRequest.ResourceId.ToString())) { m_topology.Replicas.Remove(storeRequest.ResourceId.ToString()); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ALL, String.Format("My Predecessor left. I'm now responsible for data {0}. Remove replica", storeRequest.ResourceId.ToString())); } m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} via: {3:x20} TransId={2:x16}", RELOAD_MessageCode.Store_Answer.ToString().PadRight(16, ' '), originatorID, recmsg.TransactionID, recmsg.LastHopNodeId)); //recStoreKindData = storeRequest.StoreKindData; foreach (StoreKindData store_kind in recStoreKindData) { m_topology.Store(storeRequest.ResourceId, store_kind); } /* It then sends a Store request to its successor in the neighbor * table and to that peer's successor. * * see RELOAD base -12 p.104 */ List<NodeId> replicaNodes = new List<NodeId>(); NodeId successor = m_topology.routing_table.GetApprovedSuccessor(); BigInt nextSuccsessor = successor + 1; NodeId successorsSuccessor = m_topology.routing_table.FindNextHopTo( new NodeId(nextSuccsessor.Data), true, false).Id; replicaNodes.Add(successor); replicaNodes.Add(successorsSuccessor); // send StoreAns to originator ReloadMessage storeAnswer = create_store_answ( new Destination(originatorID), recmsg.TransactionID, recStoreKindData, replicaNodes); recmsg.PutViaListToDestination(storeAnswer); //storeAnswer.addOverlayForwardingOptions(recmsg); //Proprietary //--Joscha Node nextHop = m_topology.routing_table.GetNode(recmsg.LastHopNodeId); if (m_machine is GWMachine) { //workaround in case date is stored at the gateway node responsible to route the message back into the interconnectionoverlay if (storeAnswer.forwarding_header.destination_list[0].destination_data.node_id == ((GWMachine)m_machine).GateWay.interDomainPeer.Topology.LocalNode.Id) { storeAnswer.reload_message_body.RELOAD_MsgCode = RELOAD_MessageCode.Fetch_Answer; ((GWMachine)m_machine).GateWay.interDomainPeer.Transport.receive_message(storeAnswer); } else send(storeAnswer, nextHop); } else send(storeAnswer, nextHop); // REPLICATEST // incoming store request is not a replication request if (storeRequest.Replica_number == 0) { int numberReplicas = m_topology.routing_table.Successors.Count >= 2 ? 2 : m_topology.routing_table.Successors.Count; // Replica number is max 2 // send replica to all successors for (int i = 0; i < numberReplicas; i++) { NodeId successorNode = m_topology.routing_table.Successors[i]; ReloadMessage replica = create_store_req(new Destination(successorNode), storeRequest.ResourceId, recStoreKindData, true); send(replica, m_topology.routing_table.GetNode(successorNode)); } } } else { // Signature over data in Store Request was invalid. Respond with Error Message! send(create_erro_reply(new Destination(recmsg.OriginatorID), RELOAD_ErrorCode.Error_Forbidden, "Invalid Data Signature", ++m_ReloadConfig.TransactionID), m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } } // its a StoreAns else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, String.Format("Received StoreAns from: {0}", recmsg.OriginatorID)); /* ...this allows the storing peer to independently verify that the replicas have in fact been stored. * Note that the storing peer is not require to perform this verification. * see RELOAD base -12 p.91 */ } }
private void reload_update_inbound(ReloadMessage recmsg) { UpdateReqAns req_answ = (UpdateReqAns)recmsg.reload_message_body; NodeId OriginatorID = recmsg.OriginatorID; Boolean force_send_update = false; if (recmsg.IsRequest()) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Update_Answer.ToString().PadRight(16, ' '), OriginatorID, recmsg.TransactionID)); ReloadMessage sendmsg = create_update_answ( new Destination(OriginatorID), recmsg.TransactionID, RELOAD_ErrorCode.invalid); recmsg.PutViaListToDestination(sendmsg); send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); //NodeId originator = recmsg.OriginatorID; m_topology.routing_table.SetNodeState(OriginatorID, NodeState.updates_received); m_topology.routing_table.SetFingerState(OriginatorID, NodeState.updates_received); if (req_answ.Successors.Count > 0) { m_topology.routing_table.GetNode(OriginatorID).Successors = req_answ.Successors; m_topology.routing_table.GetNode(OriginatorID).Predecessors = req_answ.Predecessors; } if (m_ReloadConfig.State == ReloadConfig.RELOAD_State.Joining) { if (m_ReloadConfig.AdmittingPeer != null && OriginatorID == m_ReloadConfig.AdmittingPeer.Id) { if (!m_topology.routing_table.IsWaitForJoinAnsw(OriginatorID)) { //we received an update from admitting peer, now joining is complete m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joined; m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joined); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("Joining completed")); m_ReloadConfig.LastJoinedTime = DateTime.Now; force_send_update = true; } } } //inform topo about incoming update Arbiter.Activate(m_DispatcherQueue, new IterativeTask<NodeId, UpdateReqAns, Boolean>( OriginatorID, req_answ, force_send_update, m_topology.routing_table.Merge)); // delete old entries in LeavingTable List<NodeId> expiredNodes = new List<NodeId>(); foreach (KeyValuePair<NodeId, DateTime> entry in m_topology.routing_table.LeavingNodes) { if (entry.Value.AddSeconds(300) < DateTime.Now) expiredNodes.Add(entry.Key); } foreach (NodeId id in expiredNodes) m_topology.routing_table.LeavingNodes.Remove(id); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TOPO, "Incoming UpdateAns"); } }
private void reload_join_inbound(ReloadMessage recmsg) { JoinReqAns req_answ = (JoinReqAns)recmsg.reload_message_body; NodeId OriginatorID = recmsg.OriginatorID; if (recmsg.IsRequest()) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Join_Answer.ToString().PadRight(16, ' '), OriginatorID, recmsg.TransactionID)); /* leaving Address and port empty, that should already be stored in link management tables */ // 5. JP MUST send a Join to AP. The AP sends the response to the // Join. RELOAD base -13 .105 ReloadMessage sendmsg = create_join_answ(new Destination(OriginatorID), recmsg.TransactionID); recmsg.PutViaListToDestination(sendmsg); send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); /* AP MUST send JP an Update explicitly labeling JP as its predecessor. */ m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Send update on join")); Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Node, Node>( m_topology.routing_table.GetNode(OriginatorID), m_topology.routing_table.GetNode(recmsg.LastHopNodeId), SendUpdate)); if (m_ReloadConfig.IsBootstrap && m_ReloadConfig.State != ReloadConfig.RELOAD_State.Joined) { m_ReloadConfig.State = ReloadConfig.RELOAD_State.Joined; m_machine.StateUpdates(ReloadConfig.RELOAD_State.Joined); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Changed to joined state")); } } else { } }
public void reload_app_attach_inbound(ReloadMessage recmsg) { AppAttachReqAns req_answ = (AppAttachReqAns)recmsg.reload_message_body; NodeId OriginatorID = recmsg.OriginatorID; Node Originator = new Node(recmsg.OriginatorID, req_answ.ice_candidates); m_topology.routing_table.AddNode(Originator); m_topology.routing_table.SetNodeState(Originator.Id, NodeState.attached); //Proprietary --joscha string destination_overlay = null; string source_overlay = null; if (recmsg.forwarding_header.fw_options != null) { foreach (ForwardingOption option in recmsg.forwarding_header.fw_options) { if (option.fwo_type == ForwardingOptionsType.destinationOverlay) { destination_overlay = System.Text.Encoding.Unicode.GetString(option.bytes); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("{0} Message for destinationOverlay=" + destination_overlay, recmsg.reload_message_body.RELOAD_MsgCode)); } if (option.fwo_type == ForwardingOptionsType.sourceOverlay) { source_overlay = System.Text.Encoding.Unicode.GetString(option.bytes); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("Message from sourceOverlay=" + source_overlay)); } } } if (destination_overlay == null)// --joscha Do not establish a connection to a different overlay if (CheckAndSetAdmittingPeer(Originator) && Originator.Id != recmsg.LastHopNodeId) // Send ping to establish a physical connection Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination(Originator.Id), PingOption.direct, SendPing)); if (source_overlay == m_ReloadConfig.OverlayName) { // Send ping to establish a physical connection Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Destination, PingOption>(new Destination(Originator.Id), PingOption.direct, SendPing)); } if (req_answ != null && req_answ.ice_candidates != null) { if (recmsg.IsRequest()) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("transport.cs - reload_app_attach_inbound")); m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.App_Attach_Answer.ToString().PadRight(16, ' '), OriginatorID, recmsg.TransactionID)); ReloadMessage sendmsg = create_app_attach_answ( new Destination(OriginatorID), recmsg.TransactionID); recmsg.PutViaListToDestination(sendmsg); //sendmsg.addOverlayForwardingOptions(recmsg); //--joscha send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("{0} <== {1} (not handled!!)", req_answ.RELOAD_MsgCode.ToString().PadRight(16, ' '), OriginatorID)); } } }
public void reload_attach_inbound(ReloadMessage recmsg) { try { AttachReqAns req_answ = (AttachReqAns)recmsg.reload_message_body; NodeId OriginatorID = recmsg.OriginatorID; if (req_answ != null && req_answ.ice_candidates != null) { //if (ReloadGlobals.UseNoIce || m_ReloadConfig.IsBootstrap) //{ //Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates); // markus, moved down //bool isFinger = m_topology.routing_table.isFinger(attacher.Id); //m_topology.routing_table.AddNode(attacher); //m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached); //} // incoming ATTACH REQUEST, so localnode is controlled agent if (recmsg.IsRequest()) { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_RELOAD, String.Format("{0} ==> {1} TransId={2:x16}", RELOAD_MessageCode.Attach_Answer.ToString().PadRight(16, ' '), OriginatorID, recmsg.TransactionID)); ReloadMessage sendmsg = create_attach_answ( new Destination(OriginatorID), recmsg.TransactionID); // log output m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Transaction ID: {0:x}", recmsg.TransactionID)); foreach (IceCandidate cand in ((AttachReqAns)sendmsg.reload_message_body).ice_candidates) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Gathered local candidate for Answer: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, sendmsg.TransactionID)); foreach (IceCandidate cand in req_answ.ice_candidates) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Request: Received remote candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID)); recmsg.PutViaListToDestination(sendmsg); //sendmsg.addOverlayForwardingOptions(recmsg); //Proprietary //--Joscha if (m_machine is GWMachine) { //workaround in case date is stored at the gateway node responsible to route the message back into the interconnectionoverlay if (sendmsg.forwarding_header.destination_list[0].destination_data.node_id == ((GWMachine)m_machine).GateWay.interDomainPeer.Topology.LocalNode.Id) { sendmsg.reload_message_body.RELOAD_MsgCode = RELOAD_MessageCode.Fetch_Answer; ((GWMachine)m_machine).GateWay.interDomainPeer.Transport.receive_message(sendmsg); } else send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } else { send(sendmsg, m_topology.routing_table.GetNode(recmsg.LastHopNodeId)); } // markus if (!ReloadGlobals.UseNoIce) // using ICE { // we only need ICE processing if localnode is a peer (in case of bootstrap we need no checks) if (!m_ReloadConfig.IsBootstrap) { #region ICE TODO // localnode is Peer => ICE processing (this is controlled node) AttachReqAns attachAnswer = (AttachReqAns)sendmsg.reload_message_body; // deep copy of local and remote ice candidates List<IceCandidate> localIceCandidatesCopy = new List<IceCandidate>(); List<IceCandidate> remoteIceCandidatesCopy = new List<IceCandidate>(); // local candidates foreach (IceCandidate cand in attachAnswer.ice_candidates) { IceCandidate deepCopy = (IceCandidate)cand.Clone(); localIceCandidatesCopy.Add(deepCopy); } // remote candidates foreach (IceCandidate cand in req_answ.ice_candidates) { IceCandidate deepCopy = (IceCandidate)cand.Clone(); remoteIceCandidatesCopy.Add(deepCopy); } // now form check list //CheckList checkList = ICE.FormCheckList(attachAnswer.ice_candidates, req_answ.ice_candidates, false); CheckList checkList = ICE.FormCheckList(localIceCandidatesCopy, remoteIceCandidatesCopy, false); ICE.PrintCandidatePairList(checkList.candidatePairs); Console.WriteLine("ThreadId: {0}, send_params einfügen: checkList count {1}", Thread.CurrentThread.ManagedThreadId, checkList.candidatePairs.Count); // Add to connection queue for (int i = 0; i < checkList.candidatePairs.Count; i++) { ReloadSendParameters send_params = new ReloadSendParameters() { connectionTableEntry = null, destinationAddress = checkList.candidatePairs[i].remoteCandidate.addr_port.ipaddr, port = checkList.candidatePairs[i].remoteCandidate.addr_port.port, buffer = null, frame = false, done = new Port<bool>(), // markus connectionSocket = null, }; // if key already exists => skip if (!GetForwardingAndLinkManagementLayer().GetConnectionQueue().ContainsKey(checkList.candidatePairs[i].remoteCandidate)) GetForwardingAndLinkManagementLayer().GetConnectionQueue().Add(checkList.candidatePairs[i].remoteCandidate, send_params); } ICE.ScheduleChecks(checkList, m_ReloadConfig.Logger); // Wait for signals of all succeded candidate pairs. Only one of the succeded candidate pairs is nominated #region signaling // wait for nomination signal List<Thread> waitingThreads = new List<Thread>(); foreach (CandidatePair candPair in checkList.candidatePairs) { if (candPair.state == CandidatePairState.Succeeded) { switch (candPair.localCandidate.tcpType) { case TcpType.Active: { if (candPair.localCandidate.activeConnectingSocket != null) { Thread waitThread = new Thread(() => { candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.activeConnectingSocket); }); waitingThreads.Add(waitThread); waitThread.Start(); } } break; case TcpType.Passive: { if (candPair.localCandidate.passiveAcceptedSocket != null) { Thread waitThread = new Thread(() => { candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.passiveAcceptedSocket); }); waitingThreads.Add(waitThread); waitThread.Start(); } } break; case TcpType.SO: { if (candPair.localCandidate.soAcceptedSocket != null) { Thread waitThread = new Thread(() => { candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.soAcceptedSocket); }); waitingThreads.Add(waitThread); waitThread.Start(); } else if (candPair.localCandidate.soConnectingSocket != null) { Thread waitThread = new Thread(() => { candPair.nominated = ICE.WaitForSignal(candPair.localCandidate.soConnectingSocket); }); waitingThreads.Add(waitThread); waitThread.Start(); } } break; } // switch } // if } // foreach // wait for all threads foreach (Thread waitingThread in waitingThreads) { waitingThread.Join(); } #endregion // choose pair CandidatePair choosenPair = null; // any nominated pair? if (checkList.candidatePairs.Any(item => item.nominated == true)) { choosenPair = checkList.candidatePairs.First(item => item.nominated == true); } // Close all sockets of all candidate pairs not nominated //for (int i = 0; i < checkList.candidatePairs.Count; i++) // if ((!checkList.candidatePairs[i].nominated) || (checkList.candidatePairs[i].state != CandidatePairState.Succeeded)) // ICE.CloseAllCandidateSockets(checkList.candidatePairs[i].localCandidate); // add node with chosen remote candidate if (choosenPair != null) { // save connection //GetForwardingAndLinkManagementLayer().SaveConnection(choosenPair); // get connection Socket socket = GetForwardingAndLinkManagementLayer().GetConnection(choosenPair); // Get IPAdress and Port of the attacher from attachers certificate cn System.Security.Cryptography.X509Certificates.X509Certificate2 tempcert = new System.Security.Cryptography.X509Certificates.X509Certificate2(recmsg.security_block.Certificates[0].Certificate); IPEndPoint attacherEndpoint = new IPEndPoint(IPAddress.Parse(tempcert.SubjectName.Name.ToString().Split(':')[1]), Convert.ToInt32( tempcert.SubjectName.Name.ToString().Split(':')[2])); // StartReloadTLSClient GetForwardingAndLinkManagementLayer().StartReloadTLSClient(OriginatorID, socket, attacherEndpoint); // for all candidates send_params.done = true for (int i = 0; i < checkList.candidatePairs.Count; i++) { ReloadSendParameters send_params; GetForwardingAndLinkManagementLayer().GetConnectionQueue().TryGetValue(checkList.candidatePairs[i].remoteCandidate, out send_params); if (send_params != null) { send_params.done.Post(true); // remove from connection queue GetForwardingAndLinkManagementLayer().GetConnectionQueue().Remove(checkList.candidatePairs[i].remoteCandidate); } } List<IceCandidate> choosenRemoteCandidates = new List<IceCandidate>(); choosenRemoteCandidates.Add(choosenPair.remoteCandidate); Node attacher = new Node(recmsg.OriginatorID, choosenRemoteCandidates); bool isFinger = m_topology.routing_table.isFinger(attacher.Id); m_topology.routing_table.AddNode(attacher); m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached); } // free all port mappings created by UPnP foreach (IceCandidate cand in attachAnswer.ice_candidates) { if (cand.cand_type == CandType.tcp_nat) { UPnP upnp = new UPnP(); bool discovered = upnp.Discover(cand.rel_addr_port.ipaddr); if (discovered) upnp.DeletePortMapping(cand.addr_port.port, ProtocolType.Tcp); } } #endregion } else { // localnode is bootstrap => no ICE processing Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates); bool isFinger = m_topology.routing_table.isFinger(attacher.Id); m_topology.routing_table.AddNode(attacher); m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached); } } // using NO ICE else { Node attacher = new Node(recmsg.OriginatorID, req_answ.ice_candidates); bool isFinger = m_topology.routing_table.isFinger(attacher.Id); m_topology.routing_table.AddNode(attacher); m_topology.routing_table.SetNodeState(recmsg.OriginatorID, NodeState.attached); } // markus end if (req_answ.SendUpdate) Arbiter.Activate(m_DispatcherQueue, new IterativeTask<Node, Node>( m_topology.routing_table.GetNode(OriginatorID), m_topology.routing_table.GetNode(recmsg.LastHopNodeId), SendUpdate)); } // incoming ATTACH ANSWER, so localnode is controlling agent // and localnode must be a peer, because bootstraps dont create attach requests and because of this cant receive an attach answer else { // using NOICE if (ReloadGlobals.UseNoIce) // markus: added if/else statement { m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_ERROR, String.Format("{0} <== {1} (not handled!!)", req_answ.RELOAD_MsgCode.ToString().PadRight(16, ' '), OriginatorID)); } // using ICE else { // get local candidates from request List<IceCandidate> localCandidates = null; bool gotLocalCandidate = m_attachRequestCandidates.TryGetValue(recmsg.TransactionID, out localCandidates); // log output m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Transaction ID: {0:x}", recmsg.TransactionID)); foreach (IceCandidate cand in localCandidates) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Got local candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID)); foreach (IceCandidate cand in req_answ.ice_candidates) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Attach Answer: Received remote candidate: {0}:{1} (TransId: {2:x})", cand.addr_port.ipaddr.ToString(), cand.addr_port.port, recmsg.TransactionID)); if (req_answ.ice_candidates != null) { // we need ice, except the answering peer is a bootstrap bool needIce = true; //// bootstrap responses with only one candidate //if (req_answ.ice_candidates.Count == 1) //{ // is it really a bootstrap? if (req_answ.ice_candidates[0].cand_type == CandType.tcp_bootstrap) { // attached to a bootstrap, so we have to do nothing here, no ice processing needed needIce = false; } //} if (needIce) { #region ICE TODO // ICE processing (this is controlling node) if (gotLocalCandidate) { // deep copy of remote ice candidates List<IceCandidate> remoteIceCandidatesCopy = new List<IceCandidate>(); // remote candidates foreach (IceCandidate cand in req_answ.ice_candidates) { IceCandidate deepCopy = (IceCandidate)cand.Clone(); remoteIceCandidatesCopy.Add(deepCopy); } //CheckList checkList = ICE.FormCheckList(localCandidates, req_answ.ice_candidates, true); CheckList checkList = ICE.FormCheckList(localCandidates, remoteIceCandidatesCopy, true); ICE.PrintCandidatePairList(checkList.candidatePairs); ICE.ScheduleChecks(checkList, m_ReloadConfig.Logger); m_attachRequestCandidates.Remove(recmsg.TransactionID); #region signaling // any succeeded pair? if (checkList.candidatePairs.Any(item => item.state == CandidatePairState.Succeeded)) { // get all succeeded pairs List<CandidatePair> succeededPairs = checkList.candidatePairs.Where(item => item.state == CandidatePairState.Succeeded).ToList(); // send nomination signal to peer bool sentSuccessfull = false; bool nominated; int counter = 0; foreach (CandidatePair pair in succeededPairs) { // simply nominate the first succeeded pair if (counter == 0) nominated = true; else nominated = false; switch (pair.localCandidate.tcpType) { case TcpType.Active: { if (pair.localCandidate.activeConnectingSocket != null) { sentSuccessfull = ICE.SendSignal(pair.localCandidate.activeConnectingSocket, nominated); pair.nominated = nominated; } } break; case TcpType.Passive: { if (pair.localCandidate.passiveAcceptedSocket != null) { sentSuccessfull = ICE.SendSignal(pair.localCandidate.passiveAcceptedSocket, nominated); pair.nominated = nominated; } } break; case TcpType.SO: { if (pair.localCandidate.soAcceptedSocket != null) { sentSuccessfull = ICE.SendSignal(pair.localCandidate.soAcceptedSocket, nominated); pair.nominated = nominated; } else if (pair.localCandidate.soConnectingSocket != null) { sentSuccessfull = ICE.SendSignal(pair.localCandidate.soConnectingSocket, nominated); pair.nominated = nominated; } } break; } // switch counter++; } // foreach if (sentSuccessfull) { } #endregion // signaling // Start Server here, if a nominated pair exists if (checkList.candidatePairs.Any(item => item.nominated)) { CandidatePair choosenPair = checkList.candidatePairs.First(item => item.nominated); // save connection here too? //GetForwardingAndLinkManagementLayer().SaveConnection(choosenPair); // get connection Socket socket = GetForwardingAndLinkManagementLayer().GetConnection(choosenPair); // StartReloadTLSServer GetForwardingAndLinkManagementLayer().StartReloadTLSServer(socket); } // if (any nominated) } // if (any succeeded pair) // Close all sockets of all candidate pairs not nominated //for (int i = 0; i < checkList.candidatePairs.Count; i++) // if ((!checkList.candidatePairs[i].nominated) || (checkList.candidatePairs[i].state != CandidatePairState.Succeeded)) // ICE.CloseAllCandidateSockets(checkList.candidatePairs[i].localCandidate); } #endregion // ICE } // existing nat candidates to free? if (localCandidates != null) { // free all port mappings created by UPnP foreach (IceCandidate cand in localCandidates) { if (cand.cand_type == CandType.tcp_nat) { UPnP upnp = new UPnP(); bool discovered = upnp.Discover(cand.rel_addr_port.ipaddr); if (discovered) upnp.DeletePortMapping(cand.addr_port.port, ProtocolType.Tcp); } } } } } } } } catch (Exception e) { throw; } }