예제 #1
0
        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);
         }
     }
 }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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;
        }
예제 #7
0
        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;
        }
예제 #8
0
        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");
                }
            }
        }
예제 #9
0
 public void ForceLeave(ClientEntry client)
 {
     lock (clientRegTable) {
         clientRegTable.Remove(client.ClientEP);
     }
 }
예제 #10
0
 public void ForceLeave(ClientEntry entry)
 {
     registrar.ForceLeave(entry);
 }
예제 #11
0
        /// <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);
                }
            }
        }
예제 #12
0
        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;
        }
 public void MarkAsActive(ClientEntry entry)
 {
     lock (clientRegTable) {
         clientRegTable.Add(entry.ClientEP, entry);
     }
 }
예제 #14
0
        /// <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);
                }
            }
        }
예제 #15
0
 public void MarkAsActive(ClientEntry entry) 
 {
     lock (clientRegTable) {
         clientRegTable.Add(entry.ClientEP, entry);
     }
 }
예제 #16
0
        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...
            }

           
           
        }
 public void ForceLeave(ClientEntry client)
 {
     lock (clientRegTable) {
         clientRegTable.Remove(client.ClientEP);
     }
 }
예제 #18
0
        public static void ForceLeave(ClientEntry client)
        {
            RegisterMessage leaveMessage = new RegisterMessage(MessageType.Leave,
                client.GroupEP.Address, client.GroupEP.Port, client.ConfirmNumber);

            ProcessLeaveRequest(leaveMessage, client.ClientIP);
        }
예제 #19
0
 public void ForceLeave(ClientEntry entry)
 {
     registrar.ForceLeave(entry);
 }