Exemplo n.º 1
0
        /// <summary>
        /// This method start the .
        /// </summary>
        public void Start()
        {
            int         size = 0;
            TrafficType traffTypes;

            lock (ThreadTypeData)
            {
                if (idxThreadTypeData < ThreadTypeData.Length)
                {
                    traffTypes = ThreadTypeData[idxThreadTypeData];
                    Thread.CurrentThread.Name = "Reflector_MCtoUC_" + 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.
            IPEndPoint ipepTmpRef = null;
            IPEndPoint ipepTmpSrv = null;
            Socket     ucRefSock  = null;
            Socket     mcSrvSock  = null;
            Socket     ucSrvSock  = null;
            int        ucPort     = 0;
            int        mcPort     = 0;


            switch (traffTypes)
            {
            case TrafficType.IPv4RTCP:
                ucPort     = ReflectorMgr.ReflectorUnicastRTPListenPort + 1;
                mcPort     = ReflectorMgr.ReflectorMulticastRTPListenPort + 1;
                ipepTmpRef = new IPEndPoint(IPAddress.IPv6Any, 0);
                ipepTmpSrv = new IPEndPoint(IPAddress.Any, 0);
                ucRefSock  = ReflectorMgr.Sockets.SockUCv6RTCP;
                mcSrvSock  = ReflectorMgr.Sockets.SockMCv4RTCP;
                ucSrvSock  = ReflectorMgr.Sockets.SockUCv4RTCP;
                break;

            case TrafficType.IPv6RTCP:
                ucPort     = ReflectorMgr.ReflectorUnicastRTPListenPort + 1;
                mcPort     = ReflectorMgr.ReflectorMulticastRTPListenPort + 1;
                ipepTmpSrv = new IPEndPoint(IPAddress.IPv6Any, 0);
                ipepTmpRef = new IPEndPoint(IPAddress.Any, 0);
                ucRefSock  = ReflectorMgr.Sockets.SockUCv4RTCP;
                mcSrvSock  = ReflectorMgr.Sockets.SockMCv6RTCP;
                ucSrvSock  = ReflectorMgr.Sockets.SockUCv6RTCP;
                break;

            case TrafficType.IPv4RTP:
                ucPort     = ReflectorMgr.ReflectorUnicastRTPListenPort;
                mcPort     = ReflectorMgr.ReflectorMulticastRTPListenPort;
                ipepTmpRef = new IPEndPoint(IPAddress.IPv6Any, 0);
                ipepTmpSrv = new IPEndPoint(IPAddress.Any, 0);
                ucRefSock  = ReflectorMgr.Sockets.SockUCv6RTP;
                mcSrvSock  = ReflectorMgr.Sockets.SockMCv4RTP;
                ucSrvSock  = ReflectorMgr.Sockets.SockUCv4RTP;
                break;

            case TrafficType.IPv6RTP:
                ucPort     = ReflectorMgr.ReflectorUnicastRTPListenPort;
                mcPort     = ReflectorMgr.ReflectorMulticastRTPListenPort;
                ipepTmpSrv = new IPEndPoint(IPAddress.IPv6Any, 0);
                ipepTmpRef = new IPEndPoint(IPAddress.Any, 0);
                ucRefSock  = ReflectorMgr.Sockets.SockUCv4RTP;
                mcSrvSock  = ReflectorMgr.Sockets.SockMCv6RTP;
                ucSrvSock  = ReflectorMgr.Sockets.SockUCv6RTP;
                break;

            default:
                Debug.Assert(false);
                throw new ArgumentException(Strings.InvalidTrafficTypeCombination);
            }
            #endregion

            IList <IPEndPoint> members = new List <IPEndPoint>();

            byte[] buf = new byte[1500];

            while (true)
            {
                try
                {
                    EndPoint            sourceEP = new IPEndPoint(IPAddress.Any, 0);
                    IPPacketInformation ipPackInfo;
                    SocketFlags         flags = SocketFlags.None;

                    size = mcSrvSock.ReceiveMessageFrom(buf, 0, buf.Length, ref flags, ref sourceEP,
                                                        out ipPackInfo);

                    IPEndPoint sourceIpe = (IPEndPoint)sourceEP;

                    registrar.MarkIPAddressAsUsingMulticast(sourceIpe.Address);

                    // If the packet's source address is the reflector's IP address then this packet
                    // was forwarded from Unicast to Multicast by the reflector. So, we shouldn't
                    // forward it to UC again. Also, "AND" this condition with source port
                    // equal to 7004/7005 to have the support running the reflector and CXPClient on the
                    // same machine.
                    if ((sourceIpe.Port != ucPort) || (!sourceIpe.Address.Equals(ReflectorMgr.MulticastInterfaceIP) &&
                                                       !sourceIpe.Address.Equals(ReflectorMgr.IPv6MulticastInterfaceIP)))
                    {
                        if ((traffTypes & TrafficType.RTP) == TrafficType.RTP)
                        {
                            ReflectorMgr.PC[ReflectorPC.ID.MulticastPacketsReceivedOther]++;
                        }

                        // Lookup the members of this multicast group.
                        IPEndPoint multicastEP = new IPEndPoint(ipPackInfo.Address, mcPort);
                        registrar.MemberLookup(members, multicastEP);

                        if (members.Count != 0)
                        {
                            // Send the data to each individual.
                            for (int j = 0; j < members.Count; j++)
                            {
                                if (members[j].AddressFamily == ucSrvSock.AddressFamily)
                                {
                                    ucSrvSock.SendTo(buf, 0, size, SocketFlags.None, members[j]);
                                }
                                else if ((ucRefSock != null) && (members[j].AddressFamily == ucRefSock.AddressFamily))
                                {
                                    ucRefSock.SendTo(buf, 0, size, SocketFlags.None, members[j]);
                                }
                            }

                            if ((traffTypes & TrafficType.RTP) == TrafficType.RTP)
                            {
                                ReflectorMgr.PC[ReflectorPC.ID.MCtoUCPacketsSent] += members.Count;
                            }
                        }
                    }
                    else if ((traffTypes & TrafficType.RTP) == TrafficType.RTP)
                    {
                        ReflectorMgr.PC[ReflectorPC.ID.MulticastPacketsReceivedSelf]++;
                    }
                }
                // 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.MCtoUCListenerException,
                                                      traffTypes, e.ToString()), EventLogEntryType.Warning, (int)ReflectorEventLog.ID.MCtoUCException);
                }
            }
        }