Esempio n. 1
0
        /// <summary>
        /// Sends a join request to RegistrarServer and returns the confirmation number. This method opens
        /// a connection to the server sends a request message, receives a response message and closes the
        /// connection to the server.
        /// </summary>
        /// <param name="groupIP">The group IP address to join</param>
        /// <param name="groupPort">The group port number to join</param>
        /// <returns>The RTP unicast port</returns>
        public int join(IPAddress groupIP, int groupPort)
        {
            try
            {
                // Creating and initializing the network related objects.
                TcpClient tcpC = new TcpClient(regSrvIP.AddressFamily);
                tcpC.Connect(regSrvIP, regSrvPort);
                NetworkStream netStream = tcpC.GetStream();
                BinaryFormatter bf = new BinaryFormatter();
                joiningMulticastEP = new IPEndPoint(groupIP, groupPort);

                // Building the message to be sent to RegistrarServer (MessageType: Join)
                RegisterMessage regMsg = new RegisterMessage(MessageType.Join, groupIP, groupPort);

                // Sending the message request object to the RegistrarSErver
                bf.Serialize(netStream,regMsg);

                // Receiving the message response object from the RegistrarServer
                Object obj = bf.Deserialize(netStream);
                regMsg = (RegisterMessage) obj;

                // Closing the server connection.
                tcpC.Close();

                // Saving the confirmation number and RTP unicast port
                refSrvCookie = regMsg.confirmNumber;
                return regMsg.unicastPort;
            } 
            catch(Exception e)
            {
                eventLog.WriteEntry("Join request to server " + regSrvIP + ":" + regSrvPort +
                    "for " + joiningMulticastEP + " failed. \n" + e.ToString(),System.Diagnostics.EventLogEntryType.Error, (int)RtpEL.ID.ReflectorJoinFailed);
                throw;
            }
        }
Esempio n. 2
0
        private static RegisterMessage ProcessLeaveRequest(RegisterMessage leaveRequestMessage, IPAddress senderIP)
        {
            try
            {
                lock (clientRegTable.SyncRoot)
                {
                    if (clientRegTable.ContainsKey(senderIP))
                    {
                        bool drop = true;
                        clientRegTable.Remove(senderIP);
                        ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count;

                        // Drop membership if no other member exists
                        foreach (ClientEntry entry in clientRegTable.Values)
                        {
                            if (entry.GroupEP.Address.Equals(leaveRequestMessage.groupIP))
                            {
                                drop = false;
                                break;
                            }
                        }

                        if (drop)
                        {
                            if (leaveRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork)
                            {
                                MulticastOption mo = new MulticastOption(leaveRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP);
                                ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                                ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                            }
                            else
                            {
                                IPv6MulticastOption mo = new IPv6MulticastOption(leaveRequestMessage.groupIP);
                                ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                                ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                            }
                        }

                        return new RegisterMessage(MessageType.Confirm, leaveRequestMessage.groupIP, leaveRequestMessage.groupPort, leaveRequestMessage.confirmNumber);
                    }
                    else
                    {   // No entries found for the leave request
                        return new RegisterMessage(MessageType.LeaveWithoutJoinError, IPAddress.Any);
                    }
                }
            }

            catch
            {
                return new RegisterMessage(MessageType.UnknownError, IPAddress.Any);
            }
        }
Esempio n. 3
0
        private static RegisterMessage ProcessJoinRequest(RegisterMessage joinRequestMessage, IPAddress senderIP)
        {
            try
            {
                // If the senderIP already exists, remove it by following the rule - the last one wins
                if (clientRegTable.ContainsKey(senderIP))
                {
                    lock (clientRegTable.SyncRoot)
                    {
                        clientRegTable.Remove(senderIP);
                    }
                }

                // Insert the new entry
                Random rnd = new Random();
                int confirmNumber = rnd.Next(1, Int32.MaxValue);

                lock (clientRegTable.SyncRoot)
                {
                    clientRegTable.Add(senderIP, new ClientEntry(senderIP, new IPEndPoint(joinRequestMessage.groupIP,
                        joinRequestMessage.groupPort), DateTime.Now, confirmNumber, DateTime.Now));

                    ReflectorMgr.PC[ReflectorPC.ID.TotalParticipants]++;
                    ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count;
                }

                joinRequestMessage.msgType = MessageType.Confirm;
                joinRequestMessage.confirmNumber = confirmNumber;
                joinRequestMessage.unicastPort = ReflectorMgr.ReflectorUnicastRTPListenPort;

                if (joinRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption mo = new MulticastOption(joinRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP);
                    ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo);
                    ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo);
                }
                else
                {
                    IPv6MulticastOption mo = new IPv6MulticastOption(joinRequestMessage.groupIP);
                    ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo);
                    ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo);
                }
            }

            catch
            {
                joinRequestMessage.msgType = MessageType.UnknownError;
            }

            return joinRequestMessage;
        }
Esempio n. 4
0
        /// <summary>
        /// Starts listening in an infinite loop for incomming connections from RegistrarClient. Here are the
        /// scenarios:
        ///   Client Request                    Client Status in Table        Table Action     Server Response to Client
        ///   -------------------               ----------------------        ------------     -------------------------
        /// 1 Msg(Join,GIP,GP,N)              (CIP, GIP, GP) entry NOT FOUND     Insert     Msg(Confirm,GIP,GP,RndConfirmNum)
        /// 2 Msg(Join,GIP,GP,N)               (CIP, GIP, GP) entry FOUND         None      Msg(ReConfirm,GIP,GP,FoundConfirmNum)
        /// 3 Msg(Leave,GIP,GP,ConfirmNum)      Entry Found ConirmNum match      Delete     Msg(Confirm,GIP,GP,FoundConfirmNum)
        /// 4 Msg(Leave,GIP,GP,ConfirmNum)     Entry Found ConirmNum mismatch     None      Msg(ConfirmNumMismatchError,0,0,0)
        /// 5 Msg(Leave,GIP,GP,ConfirmNum)          Entry Not Found               None      Msg(LeaveWithoutJoinError,0,0,0)  
        /// 6 Msg(Leave,GIP,GP,ConfirmNum)          Lookup Error                  None      Msg(UnknownError,0,0,0) 
        /// 
        /// </summary>
        public void Start()
        {
            TrafficType traffTypes = TrafficType.None;

            if (idxRSThreadTypeData < ThreadTypeData.Length)
            {
                lock (ThreadTypeData)
                {
                    traffTypes = ThreadTypeData[idxRSThreadTypeData];
                    System.Threading.Thread.CurrentThread.Name = "Reflector_RegistrarServer_" + traffTypes.ToString();
                    idxRSThreadTypeData++;
                }
            }
            else
            {
                throw new Exception("Number of created threads exceed the number of thread types defined.");
            }

            IPEndPoint localEP;

            if ((traffTypes & TrafficType.IPv6) == TrafficType.IPv6)
            {
                localEP = new IPEndPoint(IPAddress.IPv6Any,ReflectorMgr.RegistrarServerPort);
            }
            else
            {
                localEP = new IPEndPoint(IPAddress.Any,ReflectorMgr.RegistrarServerPort);
            }

            // Initializing the TCP server
            NetworkStream netStream;

            BinaryFormatter bf = new BinaryFormatter();
            Object obj;

            RegisterMessage regMsg , regMsgResponse;

            // Initializing the TcpListener

            TcpListener tcpL = new TcpListener(localEP);
            if ((traffTypes & TrafficType.IPv6) == TrafficType.IPv6)
            {
                tcpLv6 = tcpL;
            }
            else
            {
                tcpLv4 = tcpL;
            }

            tcpL.Start();
            Socket srvS = null;

            // An inifinite loop which works as follows:
            //  1. Block until a connection arrives.
            //   2. If it is a join request
            //       Lookup (ClientIP,GroupIP,GroupPort) and send back Confirm or ReConfirm
            //   2. If it is a leave request
            //       Lookup (ClientIP,GroupIP,GroupPort) and if exist send back Confirm or ConfirmNumMismatch
            //                                               if not exist send back LeaveWithoutJoinError
            //                                               if unknown error send back UnknownError
            //   2. If neither join nor leave
            //       send back InvalidRequest
            //  3. Close the connection.
            //
            while (true)
            {
                try
                {
                    srvS = tcpL.AcceptSocket();  // Can't use AcceptTcpClient since the client information is protected

                    netStream = new NetworkStream(srvS, System.IO.FileAccess.ReadWrite, true);  //Getting a network stream so I can serialize the class into it.

                    // Getting the request Object from stream
                    obj = bf.Deserialize(netStream);
                    regMsg = (RegisterMessage) obj;

                    eventLog.WriteEntry("RegistrarServer: Received Request:" + regMsg.ToString(),
                        EventLogEntryType.Information, (int)ReflectorEventLog.ID.JoinLeave);

                    switch (regMsg.msgType)
                    {
                        case MessageType.Join:
                            // Processing Join Request
                            regMsgResponse = ProcessJoinRequest(regMsg,((IPEndPoint)srvS.RemoteEndPoint).Address);
                            break;

                        case MessageType.Leave:
                            // Processing Leave Request
                            regMsgResponse = ProcessLeaveRequest(regMsg,((IPEndPoint)srvS.RemoteEndPoint).Address);
                            break;

                        default: // Invalid Message Type
                            regMsgResponse = new RegisterMessage(MessageType.InvalidRequest, IPAddress.Any);
                            break;
                    }

                    bf.Serialize(netStream, regMsgResponse);

                    netStream.Close();
                    srvS.Close();
                }
                // On stopping the service, avoid the AbortException written in the event viewer
                catch(ThreadAbortException){}
                catch (Exception e)
                {
                    eventLog.WriteEntry("RegistrarServer: Network Error while receiving/sending request message. Client: "
                        + ((srvS!=null)?((IPEndPoint) srvS.RemoteEndPoint).ToString():"") + " " + e.ToString(),
                        EventLogEntryType.Error, (int)ReflectorEventLog.ID.Error);
                }
            } // end while
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        /// <summary>
        /// Sends a leave request to RegistrarServer for groupIP and groupPort.  This method opens
        /// a connection to the server sends a request message, receives a response message and closes the
        /// connection to the server.
        /// </summary>
        /// <param name="groupIP">The group IP address to leave</param>
        /// <param name="groupPort">The group Port number to leave</param>
        /// <param name="confirmNumber">The confirmation number received from the RegistrarServer at the join time</param>
        public void leave()
        {
            try
            {
                // Creating and initializing the network related objects.
                TcpClient tcpC = new TcpClient(regSrvIP.AddressFamily);
                tcpC.Connect(regSrvIP, regSrvPort);
                NetworkStream netStream = tcpC.GetStream();
                BinaryFormatter bf = new BinaryFormatter();

                // Building the message to be sent to RegistrarServer (MessageType: Leave)
                RegisterMessage regMsg = new RegisterMessage(MessageType.Leave,joiningMulticastEP.Address, joiningMulticastEP.Port, refSrvCookie);

                // Sending the message request object to the RegistrarSErver
                bf.Serialize(netStream,regMsg);

                // Receiving the message response object from the RegistrarServer
                Object obj = bf.Deserialize(netStream);
                regMsg = (RegisterMessage) obj;

                // Closing the server connection
                tcpC.Close();
            } 
            catch (Exception e)
            {
                eventLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, Strings.LeaveRequestToServerFailed, 
                    regSrvIP, regSrvPort, joiningMulticastEP, e.ToString()), System.Diagnostics.EventLogEntryType.Error, 
                    (int)RtpEL.ID.ReflectorJoinFailed);
            }
        }