1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 namespace IceDiscovery
6 {
7     using System;
8     using System.Text;
9 
10     public sealed class PluginFactory : Ice.PluginFactory
11     {
12         public Ice.Plugin
create(Ice.Communicator communicator, string name, string[] args)13         create(Ice.Communicator communicator, string name, string[] args)
14         {
15             return new PluginI(communicator);
16         }
17     }
18 
19     public sealed class PluginI : Ice.Plugin
20     {
21         public
PluginI(Ice.Communicator communicator)22         PluginI(Ice.Communicator communicator)
23         {
24             _communicator = communicator;
25         }
26 
initialize()27         public void initialize()
28         {
29             Ice.Properties properties = _communicator.getProperties();
30 
31             bool ipv4 = properties.getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0;
32             bool preferIPv6 = properties.getPropertyAsInt("Ice.PreferIPv6Address") > 0;
33             string address;
34             if(ipv4 && !preferIPv6)
35             {
36                 address = properties.getPropertyWithDefault("IceDiscovery.Address", "239.255.0.1");
37             }
38             else
39             {
40                 address = properties.getPropertyWithDefault("IceDiscovery.Address", "ff15::1");
41             }
42             int port = properties.getPropertyAsIntWithDefault("IceDiscovery.Port", 4061);
43             string intf = properties.getProperty("IceDiscovery.Interface");
44 
45             if(properties.getProperty("IceDiscovery.Multicast.Endpoints").Length == 0)
46             {
47                 StringBuilder s = new StringBuilder();
48                 s.Append("udp -h \"").Append(address).Append("\" -p ").Append(port);
49                 if(intf.Length != 0)
50                 {
51                     s.Append(" --interface \"").Append(intf).Append("\"");
52                 }
53                 properties.setProperty("IceDiscovery.Multicast.Endpoints", s.ToString());
54             }
55 
56             string lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
57             if(lookupEndpoints.Length == 0)
58             {
59                 int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6;
60                 var interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol);
61                 foreach(string p in interfaces)
62                 {
63                     if(p != interfaces[0])
64                     {
65                         lookupEndpoints += ":";
66                     }
67                     lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
68                 }
69             }
70 
71             if(properties.getProperty("IceDiscovery.Reply.Endpoints").Length == 0)
72             {
73                 properties.setProperty("IceDiscovery.Reply.Endpoints",
74                                        "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\""));
75             }
76 
77             if(properties.getProperty("IceDiscovery.Locator.Endpoints").Length == 0)
78             {
79                 properties.setProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString());
80             }
81 
82             _multicastAdapter = _communicator.createObjectAdapter("IceDiscovery.Multicast");
83             _replyAdapter = _communicator.createObjectAdapter("IceDiscovery.Reply");
84             _locatorAdapter = _communicator.createObjectAdapter("IceDiscovery.Locator");
85 
86             //
87             // Setup locatory registry.
88             //
89             LocatorRegistryI locatorRegistry = new LocatorRegistryI(_communicator);
90             Ice.LocatorRegistryPrx locatorRegistryPrx = Ice.LocatorRegistryPrxHelper.uncheckedCast(
91                 _locatorAdapter.addWithUUID(locatorRegistry));
92 
93             Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints);
94             // No colloc optimization or router for the multicast proxy!
95             lookupPrx = lookupPrx.ice_collocationOptimized(false).ice_router(null);
96 
97             //
98             // Add lookup and lookup reply Ice objects
99             //
100             LookupI lookup = new LookupI(locatorRegistry, LookupPrxHelper.uncheckedCast(lookupPrx), properties);
101             _multicastAdapter.add(lookup, Ice.Util.stringToIdentity("IceDiscovery/Lookup"));
102 
103             _replyAdapter.addDefaultServant(new LookupReplyI(lookup), "");
104             Ice.Identity id = new Ice.Identity("dummy", "");
105             lookup.setLookupReply(LookupReplyPrxHelper.uncheckedCast(_replyAdapter.createProxy(id).ice_datagram()));
106 
107             //
108             // Setup locator on the communicator.
109             //
110             Ice.ObjectPrx loc;
111             loc = _locatorAdapter.addWithUUID(
112                 new LocatorI(lookup, Ice.LocatorRegistryPrxHelper.uncheckedCast(locatorRegistryPrx)));
113             _defaultLocator = _communicator.getDefaultLocator();
114             _locator = Ice.LocatorPrxHelper.uncheckedCast(loc);
115             _communicator.setDefaultLocator(_locator);
116 
117             _multicastAdapter.activate();
118             _replyAdapter.activate();
119             _locatorAdapter.activate();
120         }
121 
destroy()122         public void destroy()
123         {
124             if(_multicastAdapter != null)
125             {
126                 _multicastAdapter.destroy();
127             }
128             if(_replyAdapter != null)
129             {
130                 _replyAdapter.destroy();
131             }
132             if(_locatorAdapter != null)
133             {
134                 _locatorAdapter.destroy();
135             }
136             if(_communicator.getDefaultLocator().Equals(_locator))
137             {
138                 // Restore original default locator proxy, if the user didn't change it in the meantime
139                 _communicator.setDefaultLocator(_defaultLocator);
140             }
141         }
142 
143         private Ice.Communicator _communicator;
144         private Ice.ObjectAdapter _multicastAdapter;
145         private Ice.ObjectAdapter _replyAdapter;
146         private Ice.ObjectAdapter _locatorAdapter;
147         private Ice.LocatorPrx _locator;
148         private Ice.LocatorPrx _defaultLocator;
149     }
150 
151     public class Util
152     {
153         public static void
registerIceDiscovery(bool loadOnInitialize)154         registerIceDiscovery(bool loadOnInitialize)
155         {
156             Ice.Util.registerPluginFactory("IceDiscovery", new PluginFactory(), loadOnInitialize);
157         }
158     }
159 }
160