private BroadcastMessage deserialize(byte[] buf) { MemoryStream ms = new MemoryStream(buf); BroadcastMessage message = null; #if GENERIC_SERIALIZATION try { SerializedPacket p = new SerializedPacket(ms); message = (BroadcastMessage)PacketTypes.DecodeMessage(null, p); } catch (Exception e) { Trace.WriteLine(e.ToString(), this.GetType().ToString()); return(null); } #else BinaryFormatter bf = new BinaryFormatter(); try { message = (BroadcastMessage)bf.Deserialize(ms); } catch (SerializationException se) { Trace.WriteLine("Failed to deserialize a BroadcastMessage: " + se.Message, this.GetType().ToString()); return(null); } catch (Exception e) { Trace.WriteLine(e.ToString(), this.GetType().ToString()); return(null); } #endif return(message); }
private void ReceiveCallback(IAsyncResult ar) { UdpClient u = (UdpClient)ar.AsyncState; byte[] receiveBuf = null; IPEndPoint remoteEP = null; try { receiveBuf = u.EndReceive(ar, ref remoteEP); } catch (ObjectDisposedException ode) { Trace.WriteLine("ReceiveCallback: " + ode.Message, this.GetType().ToString()); } catch (Exception e) { Trace.WriteLine("ReceiveCallback exception: " + e.ToString(), this.GetType().ToString()); } finally { m_MessageReceived.Set(); //Let the listen thread continue. } if (receiveBuf != null) { BroadcastMessage message = deserialize(receiveBuf); if (message != null) { if (message.SenderID != m_LocalSenderID) { processMessage(message, DateTime.Now); } } } }
/// <summary> /// Update the broadcast message /// </summary> private void UpdateMessage() { lock (m_BufferSyncObject) { BroadcastMessage message = new BroadcastMessage(m_ServerEP, m_ParticipantName, m_ServerID, m_PresentationName, m_showIP); m_MessageBuffer = Serialize(message, out m_MessageBufferLength); } }
/// <summary> /// Handle one inbound BroadcastMessage /// </summary> /// <param name="message"></param> /// <param name="timestamp"></param> private void processMessage(BroadcastMessage message, DateTime timestamp) { //List<InstructorAdvertisement> nonLocalPublicSubnets = new List<InstructorAdvertisement>(); foreach (IPEndPoint ep in message.EndPoints) { InstructorAdvertisement ia = new InstructorAdvertisement(ep, message.HumanName, message.PresentationName, message.SenderID, message.ShowIP); using(Synchronizer.Lock(this.SyncRoot)) { if (m_InstructorAdvertisements.Contains(ia)) { //We already have the entry, just update the timestamp. int index = m_InstructorAdvertisements.IndexOf(ia); m_InstructorAdvertisements[index].Timestamp = DateTime.Now; continue; } if (ep.AddressFamily.Equals(AddressFamily.InterNetwork)) { //IPv4 if (!isPrivateSubnet(ep.Address)) { //If there are both local and non-local public subnets, keep only the local ones (plus multicast) if (matchesAnyLocalSubnet(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); //Not a private subnet, add to the table. } else if (isMulticastAddress(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); ia.Multicast = true; m_InstructorAdvertisements.Add(ia); //Not a private subnet, add to the table. } else { //nonLocalPublicSubnets.Add(ia); } } else { //If it is a private subnet, the listener also needs to be on that subnet //In effect, we can't talk to NAT'ed hosts directly unless we are also on the same NAT'ed network. //Otherwise, we would have to connect to a port forwarding router. if (matchesAnyLocalSubnet(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); } } } else if (ep.AddressFamily.Equals(AddressFamily.InterNetworkV6)) { if (BroadcastManager.UseIPv6) { //Don't show any IPv6 entries unless IPv6 is enabled on the local system. //TODO: To correctly handle link local and site local, we need to do a bit more work here. Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); } } } } //Are there cases were we would want to show the non-local public subnet addresses? }
/// <summary> /// Handle one inbound BroadcastMessage /// </summary> /// <param name="message"></param> /// <param name="timestamp"></param> private void processMessage(BroadcastMessage message, DateTime timestamp) { //List<InstructorAdvertisement> nonLocalPublicSubnets = new List<InstructorAdvertisement>(); foreach (IPEndPoint ep in message.EndPoints) { InstructorAdvertisement ia = new InstructorAdvertisement(ep, message.HumanName, message.PresentationName, message.SenderID, message.ShowIP); using (Synchronizer.Lock(this.SyncRoot)) { if (m_InstructorAdvertisements.Contains(ia)) //We already have the entry, just update the timestamp. { int index = m_InstructorAdvertisements.IndexOf(ia); m_InstructorAdvertisements[index].Timestamp = DateTime.Now; continue; } if (ep.AddressFamily.Equals(AddressFamily.InterNetwork)) //IPv4 { if (!isPrivateSubnet(ep.Address)) { //If there are both local and non-local public subnets, keep only the local ones (plus multicast) if (matchesAnyLocalSubnet(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); //Not a private subnet, add to the table. } else if (isMulticastAddress(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); ia.Multicast = true; m_InstructorAdvertisements.Add(ia); //Not a private subnet, add to the table. } else { //nonLocalPublicSubnets.Add(ia); } } else { //If it is a private subnet, the listener also needs to be on that subnet //In effect, we can't talk to NAT'ed hosts directly unless we are also on the same NAT'ed network. //Otherwise, we would have to connect to a port forwarding router. if (matchesAnyLocalSubnet(ep.Address)) { Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); } } } else if (ep.AddressFamily.Equals(AddressFamily.InterNetworkV6)) { if (BroadcastManager.UseIPv6) { //Don't show any IPv6 entries unless IPv6 is enabled on the local system. //TODO: To correctly handle link local and site local, we need to do a bit more work here. Trace.WriteLine("Adding Instructor Table Entry: " + ia.ToString(), this.GetType().ToString()); m_InstructorAdvertisements.Add(ia); } } } } //Are there cases were we would want to show the non-local public subnet addresses? }