public IEnumerator<ITask> Send(Node node, ReloadMessage reloadMessage) // node is remote peer { ReloadConnectionTableEntry connectionTableEntry = null; List<Byte[]> ByteArrayList = new List<byte[]>(); ByteArrayList.Add(reloadMessage.ToBytes()); //if (ReloadGlobals.FRAGMENTATION == true) { if (reloadMessage.forwarding_header.length > ReloadGlobals.MAX_PACKET_BUFFER_SIZE * ReloadGlobals.MAX_PACKETS_PER_RECEIVE_LOOP) { if (ByteArrayList[0].Length > ReloadGlobals.FRAGMENT_SIZE) { //TODO: fragment size should not be fix ByteArrayList.Clear(); ByteArrayList = reloadMessage.ToBytesFragmented(ReloadGlobals.FRAGMENT_SIZE); } } foreach (byte[] ByteArray in ByteArrayList) { /* Try to find a matching connection using node id or target address*/ if (node.Id != null) { connectionTableEntry = connectionTable.lookupEntry(node.Id); if (connectionTableEntry != null) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("FLM: Found open connection for target node id {0}", node.Id)); } if (connectionTableEntry == null) { // connectionTableEntry == null => no connection to remote peer List<IceCandidate> icecandidates = node.IceCandidates; // remote peer candidates if (icecandidates != null) { foreach (IceCandidate candidate in icecandidates) { switch (candidate.addr_port.type) { case AddressType.IPv6_Address: case AddressType.IPv4_Address: { ReloadSendParameters send_params; // check if there is already a attempt to open a connection to this node //if (connectionQueue.ContainsKey(candidate.addr_port)) if (connectionQueue.ContainsKey(candidate)) { // here we have a connection attempt m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("Connection Pending!!!!!!!!!!!!!!!!!!!!!!!!!!!")); //send_params = connectionQueue[candidate.addr_port]; send_params = connectionQueue[candidate]; yield return Arbiter.Receive(false, send_params.done, x => { }); send_params.done.Post(true); //maybe there are still some other pending connections? if (send_params.connectionTableEntry != null) //do we have a valid connection? { // here we have a valid connection connectionTableEntry = send_params.connectionTableEntry; if (send_params.connectionTableEntry.NodeID != null) //TODO: correct? node.Id = send_params.connectionTableEntry.NodeID; m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_WARNING, String.Format("DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!")); //connectionQueue.Remove(candidate.addr_port); connectionQueue.Remove(candidate); if (node.Id != null) { connectionTableEntry = connectionTable.lookupEntry(node.Id); if (connectionTableEntry != null) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_SOCKET, String.Format("FLM: Found open connection for target node id {0}", node.Id)); send_params = new ReloadSendParameters() { connectionTableEntry = connectionTableEntry, destinationAddress = null, port = 0, buffer = ByteArray, frame = true, done = new Port<bool>(), // markus connectionSocket = null, }; yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send)); // SEND break; } } // here we have no valid connection, but a connection attempt (maybe break?) //break; // markus } // no connection attempt (maybe else here?) // here is no existing connection and no attempt => try to connect // NO ICE or ICE but bootstrap if (ReloadGlobals.UseNoIce || candidate.cand_type == CandType.tcp_bootstrap) { connectionTableEntry = connectionTable.lookupEntry(new IPEndPoint(candidate.addr_port.ipaddr, candidate.addr_port.port)); if (connectionTableEntry != null) m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("FLM: Found open connection for target IP {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port)); else m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("Opening connection to {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port)); send_params = new ReloadSendParameters() { connectionTableEntry = connectionTableEntry, destinationAddress = candidate.addr_port.ipaddr, port = candidate.addr_port.port, buffer = ByteArray, frame = true, done = new Port<bool>(), // markus connectionSocket = null, }; //send_params.done.Post(false); //connectionQueue[candidate.addr_port] = send_params; connectionQueue[candidate] = send_params; //m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_INFO, String.Format("Insert {0}:{1} into connectionQueue", new IPAddress(send_params.destinationAddress.Address).ToString(), send_params.port)); yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send)); // SEND //connectionQueue.Remove(candidate.addr_port); connectionQueue.Remove(candidate); if (send_params.connectionTableEntry != null) { connectionTableEntry = send_params.connectionTableEntry; //TODO: not nice but does the trick if (send_params.connectionTableEntry.NodeID != null) //TODO: correct? node.Id = send_params.connectionTableEntry.NodeID; } } // ICE peer //else //{ // connectionTableEntry = connectionTable.lookupEntry(new IPEndPoint(candidate.addr_port.ipaddr, candidate.addr_port.port)); // if (connectionTableEntry != null) // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("FLM: Found open connection for target IP {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port)); // else // m_ReloadConfig.Logger(ReloadGlobals.TRACEFLAGS.T_TRANSPORT, String.Format("Opening connection to {0}:{1}", candidate.addr_port.ipaddr, candidate.addr_port.port)); // // try to get connection // Socket connectionSocket = null; // m_connectionsToRemotePeer.TryGetValue(candidate.addr_port, out connectionSocket); // //if (connectionSocket == null) // // continue; //versuche mit nächsten candidate // send_params = new ReloadSendParameters() // { // connectionTableEntry = connectionTableEntry, // destinationAddress = candidate.addr_port.ipaddr, // port = candidate.addr_port.port, // buffer = ByteArray, // frame = true, // done = new Port<bool>(), // // markus // connectionSocket = connectionSocket, // }; // //send_params.done.Post(false); // connectionQueue[candidate.addr_port] = send_params; // yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send)); // SEND // connectionQueue.Remove(candidate.addr_port); // if (send_params.connectionTableEntry != null) // { // connectionTableEntry = send_params.connectionTableEntry; //TODO: not nice but does the trick // if (send_params.connectionTableEntry.NodeID != null) //TODO: correct? // node.Id = send_params.connectionTableEntry.NodeID; // } //} } break; } //just support one ice candidate only here break; } // foreach ice candidate } } else { // connectionTableEntry != null => existing connection to remote peer ReloadSendParameters send_params = new ReloadSendParameters() { connectionTableEntry = connectionTableEntry, destinationAddress = null, port = 0, buffer = ByteArray, frame = true, done = new Port<bool>(), }; yield return Arbiter.ExecuteToCompletion(m_DispatcherQueue, new IterativeTask<Node, ReloadSendParameters>(node, send_params, link.Send)); // SEND } } // foreach ByteArray yield break; } // Send
public IEnumerator<ITask> Send(Node node, ReloadMessage reloadMessage) { if (m_ReloadConfig.State < ReloadConfig.RELOAD_State.Exit) Arbiter.Activate(m_ReloadConfig.DispatcherQueue, new IterativeTask<Node, byte[]>(node, reloadMessage.ToBytes(), link.Send)); yield break; }