public static void ForceLeave(ClientEntry client) { RegisterMessage leaveMessage = new RegisterMessage(MessageType.Leave, client.GroupEP.Address, client.GroupEP.Port, client.ConfirmNumber); ProcessLeaveRequest(leaveMessage, client.ClientIP); }
public void ProcessMessage(UdpReflectorMessage message, IPEndPoint source, Socket localSocket) { IPEndPoint localEP = localSocket.LocalEndPoint as IPEndPoint; if (message.Type == UdpReflectorMessageType.LEAVE) { // a background thread will eventually remove the multicast group, if necessary lock (clientRegTable) { clientRegTable.Remove(source); } return; } else if (message.Type == UdpReflectorMessageType.JOIN) { IPEndPoint multicastEP = message.MulticastEP; JoinMulticastGroup(multicastEP); subscribedMulticastGroups[multicastEP.Address] = multicastEP.Address; ClientEntry entry = new ClientEntry(source, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(source, entry); } // Multi-reflector cascading join, if required. We send an identical join request on the // same port to the parent's IP address if (ParentReflector != null) { IPEndPoint parentEP = new IPEndPoint(ParentReflector, localEP.Port); UdpReflectorMessage joinMessage = new UdpReflectorMessage(UdpReflectorMessageType.JOIN, multicastEP); BufferChunk chunk = joinMessage.ToBufferChunk(); localSocket.SendTo(chunk.Buffer, chunk.Index, chunk.Length, SocketFlags.None, parentEP); // Need to add the parent to our local dispatch table (to simulate a remote join) ClientEntry parentEntry = new ClientEntry(parentEP, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(parentEP, parentEntry); } } } else if (message.Type == UdpReflectorMessageType.PING) { // acknowledge that we're alive... UdpReflectorMessage pingReply = new UdpReflectorMessage(UdpReflectorMessageType.PING_REPLY); BufferChunk bufferChunk = pingReply.ToBufferChunk(); localSocket.SendTo(bufferChunk.Buffer, bufferChunk.Index, bufferChunk.Length, SocketFlags.None, source); } else { // unknown or unhandled message type... } }
/// <summary> /// This method gets an IP address as the input and returns the group IP and port /// which this client has joined before. /// </summary> public IPEndPoint GroupLookup(IPEndPoint clientEP) { lock (clientRegTable) { if (clientRegTable.ContainsKey(clientEP)) { ClientEntry entry = clientRegTable[clientEP]; return(entry.GroupEP); } else { return(null); } } }
/// <summary> /// This method gets an IP address as the input and returns the group IP and port /// which this client has joined before. /// </summary> public static IPEndPoint GroupLookup(IPAddress clientIP) { IPEndPoint foundGroup = null; lock (clientRegTable.SyncRoot) { ClientEntry entry = (ClientEntry)clientRegTable[clientIP]; if (entry != null) { foundGroup = entry.GroupEP; } } return(foundGroup); }
public ClientEntry[] GetClientTable() { ClientEntry[] clientTable = null; lock (registrar.ClientRegTable) { int count = registrar.ClientRegTable.Count; if (count > 0) { clientTable = new ClientEntry[count]; registrar.ClientRegTable.Values.CopyTo(clientTable, 0); } } return(clientTable); }
public ClientEntry[] GetClientTable() { ClientEntry[] clientTable = null; lock (registrar.ClientRegTable) { int count = registrar.ClientRegTable.Count; if (count > 0) { clientTable = new ClientEntry[count]; registrar.ClientRegTable.Values.CopyTo(clientTable, 0); } } return clientTable; }
private void RefreshClientTable() { ClientEntry[] clientTable = null; lock (RegistrarServer.ClientRegTable.SyncRoot) { int count = RegistrarServer.ClientRegTable.Count; if (count > 0) { clientTable = new ClientEntry[count]; RegistrarServer.ClientRegTable.Values.CopyTo(clientTable, 0); } } tableListBox.DataSource = clientTable; }
private void forceLeaveBtn_Click(object sender, System.EventArgs e) { ClientEntry entry = (ClientEntry)tableListBox.SelectedItem; // List is not empty if (entry != null) { if (RegistrarServer.ClientRegTable.ContainsKey(entry.ClientIP)) { RegistrarServer.ForceLeave(entry); RefreshClientTable(); } else { MessageBox.Show(this, "The Client IP address does not exist. " + "Click the Refresh button to get the current list.", "ConferenceXP Reflector"); } } }
public void ForceLeave(ClientEntry client) { lock (clientRegTable) { clientRegTable.Remove(client.ClientEP); } }
public void ForceLeave(ClientEntry entry) { registrar.ForceLeave(entry); }
/// <summary> /// Forwards the traffic from unicast to unicast/multicast for the given trafficType /// </summary> public void Start() { int size = 0; TrafficType traffTypes; lock (ThreadTypeData) { if (idxThreadTypeData < ThreadTypeData.Length) { traffTypes = ThreadTypeData[idxThreadTypeData]; Thread.CurrentThread.Name = "Reflector_UCtoUCMC_" + traffTypes.ToString(); idxThreadTypeData++; } else { throw new Exception(Strings.CreatedThreadsExceedThreadTypesDefined); } } #region Assigning appropriate sockets to "(mc/uc)(Ref/Srv)Sock" // The Ref(erence) socket variables are assigned to the socket protocol that this thread is not listening on // but may use for inter-protocol communication. For example if mcSrvSock is an IPv4 socket, mcRefSock would be // an IPv6 socket and vice versa. Socket mcRefSock = null; Socket ucRefSock = null; Socket ucSrvSock = null; int ucPort = 0; EndPoint remoteEP = null; switch (traffTypes) { case TrafficType.IPv4RTCP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort + 1; remoteEP = new IPEndPoint(IPAddress.Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv6RTCP; ucRefSock = ReflectorMgr.Sockets.SockUCv6RTCP; ucSrvSock = ReflectorMgr.Sockets.SockUCv4RTCP; break; case TrafficType.IPv6RTCP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort + 1; remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv4RTCP; ucRefSock = ReflectorMgr.Sockets.SockUCv4RTCP; ucSrvSock = ReflectorMgr.Sockets.SockUCv6RTCP; break; case TrafficType.IPv4RTP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort; remoteEP = new IPEndPoint(IPAddress.Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv6RTP; ucRefSock = ReflectorMgr.Sockets.SockUCv6RTP; ucSrvSock = ReflectorMgr.Sockets.SockUCv4RTP; break; case TrafficType.IPv6RTP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort; remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv4RTP; ucRefSock = ReflectorMgr.Sockets.SockUCv4RTP; ucSrvSock = ReflectorMgr.Sockets.SockUCv6RTP; break; default: Debug.Assert(false); throw new ArgumentException(Strings.InvalidTrafficTypeCombination); } #endregion IPEndPoint groupEP = null; byte [] buf = new byte[1500]; IList <IPEndPoint> members = new List <IPEndPoint>(); while (true) { try { //EndPoint ep = null; size = ucSrvSock.ReceiveFrom(buf, ref remoteEP); // First, check whether this is a control message (JOIN or LEAVE) if (size <= 50) { try { UdpReflectorMessage message = new UdpReflectorMessage(buf, size); registrar.ProcessMessage(message, remoteEP as IPEndPoint, ucSrvSock); continue; // read next message } catch (InvalidUdpReflectorMessage) { // fall through } } if ((traffTypes & TrafficType.RTP) == TrafficType.RTP) { ReflectorMgr.PC[ReflectorPC.ID.UnicastPacketsReceived]++; } ClientEntry entry = registrar.GetEntry(remoteEP as IPEndPoint); if (entry != null) { registrar.MarkAsActive(entry); // Make sure this node isn't also sending over multicast... if (registrar.IsIPAddressUsingMulticast(entry.ClientEP.Address)) { eventLog.WriteEntry("Warning: receving both unicast and multicast from: " + entry.ClientEP.Address, EventLogEntryType.Warning, (int)ReflectorEventLog.ID.UCtoUCMCException); continue; // read next message without propogating further... } // lookup the (first) group which this client is a member of that group. groupEP = entry.GroupEP; // Find the other members of the group registrar.MemberLookup(members, groupEP); // Send the data to the Multicast side if (SendMulticast) { if (groupEP.AddressFamily == ucSrvSock.AddressFamily) { ucSrvSock.SendTo(buf, 0, size, SocketFlags.None, groupEP); } else if ((mcRefSock != null) && (groupEP.AddressFamily == ucRefSock.AddressFamily)) { ucRefSock.SendTo(buf, 0, size, SocketFlags.None, groupEP); } } // Send the data to all unicast client members except the sender. for (int i = 0; i < members.Count; i++) { if (!remoteEP.Equals(members[i])) { if (members[i].AddressFamily == ucSrvSock.AddressFamily) { ucSrvSock.SendTo(buf, 0, size, SocketFlags.None, members[i]); } else if ((ucRefSock != null) && (members[i].AddressFamily == ucRefSock.AddressFamily)) { ucRefSock.SendTo(buf, 0, size, SocketFlags.None, members[i]); } } } if ((traffTypes & TrafficType.RTP) == TrafficType.RTP) { ReflectorMgr.PC[ReflectorPC.ID.UCtoUCPacketsSent] += members.Count - 1; } } } // On stopping the service, avoid the AbortException written in the event viewer catch (ThreadAbortException) {} catch (Exception e) // Connection reset by peer! this happens occasionally when a UC client leaves. { eventLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, Strings.UCtoUCMCForwarderException, traffTypes, remoteEP, e.ToString()), EventLogEntryType.Warning, (int)ReflectorEventLog.ID.UCtoUCMCException); } } }
public void MarkAsActive(ClientEntry entry) { lock (clientRegTable) { clientRegTable.Add(entry.ClientEP, entry); } }
/// <summary> /// Forwards the traffic from unicast to unicast/multicast for the given trafficType /// </summary> public void Start() { int size = 0; TrafficType traffTypes; lock (ThreadTypeData) { if (idxThreadTypeData < ThreadTypeData.Length) { traffTypes = ThreadTypeData[idxThreadTypeData]; Thread.CurrentThread.Name = "Reflector_UCtoUCMC_" + traffTypes.ToString(); idxThreadTypeData++; } else { throw new Exception("Number of created threads exceed the number of thread types defined."); } } #region Assigning appropriate sockets to "(mc/uc)(Ref/Srv)Sock" // The Ref(erence) socket variables are assigned to the socket protocol that this thread is not listening on // but may use for inter-protocol communication. For example if mcSrvSock is an IPv4 socket, mcRefSock would be // an IPv6 socket and vice versa. Socket mcRefSock = null; Socket ucRefSock = null; Socket ucSrvSock = null; int ucPort = 0; EndPoint remoteEP = null; switch (traffTypes) { case TrafficType.IPv4RTCP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort + 1; remoteEP = new IPEndPoint(IPAddress.Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv6RTCP; ucRefSock = ReflectorMgr.Sockets.SockUCv6RTCP; ucSrvSock = ReflectorMgr.Sockets.SockUCv4RTCP; break; case TrafficType.IPv6RTCP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort + 1; remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv4RTCP; ucRefSock = ReflectorMgr.Sockets.SockUCv4RTCP; ucSrvSock = ReflectorMgr.Sockets.SockUCv6RTCP; break; case TrafficType.IPv4RTP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort; remoteEP = new IPEndPoint(IPAddress.Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv6RTP; ucRefSock = ReflectorMgr.Sockets.SockUCv6RTP; ucSrvSock = ReflectorMgr.Sockets.SockUCv4RTP; break; case TrafficType.IPv6RTP: ucPort = ReflectorMgr.ReflectorUnicastRTPListenPort; remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); mcRefSock = ReflectorMgr.Sockets.SockMCv4RTP; ucRefSock = ReflectorMgr.Sockets.SockUCv4RTP; ucSrvSock = ReflectorMgr.Sockets.SockUCv6RTP; break; default: Debug.Assert(false); throw new ArgumentException("Invalid traffic type combination"); } #endregion IPAddress remoteIP = null; IPEndPoint groupEP = null; byte [] buf = new byte[1500]; ArrayList members = new ArrayList(); while (true) { try { size = ucSrvSock.ReceiveFrom(buf, ref remoteEP); if ((traffTypes & TrafficType.RTP) == TrafficType.RTP) { ReflectorMgr.PC[ReflectorPC.ID.UnicastPacketsReceived]++; } else if ((traffTypes & TrafficType.RTCP) == TrafficType.RTCP) { // Update client's last RTCP property ClientEntry entry = (ClientEntry)RegistrarServer.ClientRegTable[((IPEndPoint)remoteEP).Address]; entry.LastRTCP = DateTime.Now; } // lookup the (first) group which this client is a member of that group. remoteIP = ((IPEndPoint)remoteEP).Address; groupEP = RegistrarServer.GroupLookup(remoteIP); if (groupEP != null) { // Find the other members of the group RegistrarServer.MemberLookup(members, groupEP.Address, groupEP.Port); if ((traffTypes & TrafficType.RTCP) == TrafficType.RTCP) { groupEP = new IPEndPoint(groupEP.Address, groupEP.Port + 1); } // Send the data to the Multicast side if (groupEP.AddressFamily == ucSrvSock.AddressFamily) { ucSrvSock.SendTo(buf, 0, size, SocketFlags.None, groupEP); } else if ((mcRefSock != null) && (groupEP.AddressFamily == ucRefSock.AddressFamily)) { ucRefSock.SendTo(buf, 0, size, SocketFlags.None, groupEP); } // Send the data to all unicast client members except the sender. for (int i = 0; i < members.Count; i++) { if (!remoteIP.Equals((IPAddress)members[i])) { if (((IPAddress)members[i]).AddressFamily == ucSrvSock.AddressFamily) { ucSrvSock.SendTo(buf, 0, size, SocketFlags.None, new IPEndPoint((IPAddress)members[i], ucPort)); } else if ((ucRefSock != null) && (((IPAddress)members[i]).AddressFamily == ucRefSock.AddressFamily)) { ucRefSock.SendTo(buf, 0, size, SocketFlags.None, new IPEndPoint((IPAddress)members[i], ucPort)); } } } if ((traffTypes & TrafficType.RTP) == TrafficType.RTP) { ReflectorMgr.PC[ReflectorPC.ID.UCtoUCPacketsSent] += members.Count - 1; } } } // On stopping the service, avoid the AbortException written in the event viewer catch (ThreadAbortException) {} catch (Exception e) // Connection reset by peer! this happens occasionally when a UC client leaves. { eventLog.WriteEntry("UCtoUCMC forwarder exception - TrafficType:" + traffTypes + " Packet received from: " + remoteEP + "\n" + e.ToString(), EventLogEntryType.Warning, (int)ReflectorEventLog.ID.UCtoUCMCException); } } }
public void ProcessMessage(UdpReflectorMessage message,IPEndPoint source,Socket localSocket) { IPEndPoint localEP = localSocket.LocalEndPoint as IPEndPoint; if (message.Type == UdpReflectorMessageType.LEAVE) { // a background thread will eventually remove the multicast group, if necessary lock (clientRegTable) { clientRegTable.Remove(source); } return; } else if (message.Type == UdpReflectorMessageType.JOIN) { IPEndPoint multicastEP = message.MulticastEP; JoinMulticastGroup(multicastEP); subscribedMulticastGroups[multicastEP.Address] = multicastEP.Address; ClientEntry entry = new ClientEntry(source, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(source, entry); } // Multi-reflector cascading join, if required. We send an identical join request on the // same port to the parent's IP address if (ParentReflector != null) { IPEndPoint parentEP = new IPEndPoint(ParentReflector, localEP.Port); UdpReflectorMessage joinMessage = new UdpReflectorMessage(UdpReflectorMessageType.JOIN, multicastEP); BufferChunk chunk = joinMessage.ToBufferChunk(); localSocket.SendTo(chunk.Buffer, chunk.Index, chunk.Length, SocketFlags.None,parentEP); // Need to add the parent to our local dispatch table (to simulate a remote join) ClientEntry parentEntry = new ClientEntry(parentEP, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(parentEP, parentEntry); } } } else if (message.Type == UdpReflectorMessageType.PING) { // acknowledge that we're alive... UdpReflectorMessage pingReply = new UdpReflectorMessage(UdpReflectorMessageType.PING_REPLY); BufferChunk bufferChunk = pingReply.ToBufferChunk(); localSocket.SendTo(bufferChunk.Buffer, bufferChunk.Index, bufferChunk.Length, SocketFlags.None, source); } else { // unknown or unhandled message type... } }