public DNSMultiCast(Jenkins hudson) { if (disabled) return; // escape hatch try { this.jmdns = JmDNS.create(); Map<String, String> props = new HashMap<String, String>(); String rootURL = hudson.getRootUrl(); if (rootURL != null) props.put("url", rootURL); try { props.put("version", String.valueOf(Jenkins.getVersion())); } catch (IllegalArgumentException e) { // failed to parse the version number } TcpSlaveAgentListener tal = hudson.getTcpSlaveAgentListener(); if (tal != null) props.put("slave-port", String.valueOf(tal.getPort())); props.put("server-id", Util.getDigestOf(hudson.getSecretKey())); URL jenkins_url = new URL(rootURL); int jenkins_port = jenkins_url.getPort(); if (jenkins_port == -1) { jenkins_port = 80; } if (jenkins_url.getPath().length() > 0) { props.put("path", jenkins_url.getPath()); } jmdns.registerService( ServiceInfo.create( "_hudson._tcp.local.", "hudson", jenkins_port, 0, 0, props)); // for backward compatibility jmdns.registerService( ServiceInfo.create("_jenkins._tcp.local.", "jenkins", jenkins_port, 0, 0, props)); // Make Jenkins appear in Safari's Bonjour bookmarks jmdns.registerService( ServiceInfo.create("_http._tcp.local.", "Jenkins", jenkins_port, 0, 0, props)); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to advertise the service to DNS multi-cast", e); } }
// Implementation methods // ------------------------------------------------------------------------- protected ServiceInfo createServiceInfo(String name, Map map) { int port = MapHelper.getInt(map, "port", 0); String type = getType(); if (LOG.isDebugEnabled()) { LOG.debug("Registering service type: " + type + " name: " + name + " details: " + map); } return ServiceInfo.create(type, name + "." + type, port, weight, priority, ""); }
/** * Publish local node configuration via multicast * * @param serviceName name of service to be published. (e.g. release version for installation) * instanceName name of instance which is publishing. (e.g. the local node id etc.) nodeConfig * info to be published publishTime how long the info would be published */ public void publish( String serviceName, String instanceName, Map<String, String> values, long publishTime) throws IOException { ServiceInfo info = ServiceInfo.create("_" + serviceName + "._tcp.local.", instanceName, 9999, 0, 0, values); this.jmdns.registerService(info); if (publishTime > 0) { sleep(publishTime); this.close(); } }
@SuppressWarnings("boxing") @Thread(isDaemonic = true) public void backgroundInit() { // (Ralf:) zomfg, this is one of the worst hacks i've done the last // couple of months. Deep within jmdns we placed a variable to // override a check if it is already save to transmit something. jmDNS // usually takes 5 seconds to reach that state, but that's // too long for us. If you set this variable the check will be skipped // and the request should take place much faster. // Appears to work(tm). ServiceResolver.ANNOUNCE_OVERRIDE = true; final PluginConfigurationUtil pcu = new PluginConfigurationUtil(this.pluginConfiguration); this.startupLock = pcu.getInt(RemoteDiscovery.class, "startup.locktime", 1000); this.lockMode = pcu.getString(RemoteDiscovery.class, "startup.lockmode", "onepass"); // TODO put this in a thread this.checkCache.loadCache(); try { this.jmdnsLock.lock(); this.jmdns = JmDNS .create(); // Maybe init with local loopback in case no other network card is present, // otherwise returns null this.timeOfStartup = System.currentTimeMillis(); final int port = getFreePort(); final ServiceInfo service = ServiceInfo.create(TYPE, NAME + " @" + this.timeOfStartup, port, 0, 0, EXPORT_NAME); this.localManagerExportServer = Proxies.newServer(EXPORT_NAME, port, (DiscoveryManager) this.localManager); this.jmdns.registerService(service); // Set it again, this time for the lock below this.timeOfStartup = System.currentTimeMillis(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalStateException e) { this.logger.warning("Error starting discovery."); } finally { this.startupLatch.countDown(); this.jmdnsLock.unlock(); } // and load our cache... // todo make this configurable... // this.checkCache.loadCache(fileName) }
@SuppressWarnings("boxing") public void backgroundInit() { // (Ralf:) zomfg, this is one of the worst hacks i've done the last years. Deep within jmdns we // placed a variable to // override a check if it is already safe to transmit something. jmDNS usually takes 5 seconds // to reach that state, but that's // too long for us. If you set this variable the check will be skipped and the request should // take place much faster. // Appears to work(tm). ServiceResolver.ANNOUNCE_OVERRIDE = true; this.logger.status("backgroundinit/start"); final PluginConfigurationUtil pcu = new PluginConfigurationUtil(this.pluginConfiguration); this.startupLock = pcu.getInt(RemoteDiscovery.class, "startup.locktime", 1000); this.lockMode = pcu.getString(RemoteDiscovery.class, "startup.lockmode", "onepass"); try { this.logger.status("backgroundinit/lock"); this.jmdnsLock.lock(); this.jmdns = JmDNS .create(); // Maybe init with local loopback in case no other network card is present, // otherwise returns null this.timeOfStartup = System.currentTimeMillis(); final int port = RemoteDiscoveryImpl.getFreePort(); final ServiceInfo service = ServiceInfo.create(TYPE, NAME + " @" + this.timeOfStartup, port, 0, 0, EXPORT_NAME); this.logger.status("backgroundinit/export", "port", port); this.localManagerExportServer = Proxies.newServer(EXPORT_NAME, port, (DiscoveryManager) this.localTCPIPManager); this.logger.status("backgroundinit/announce", "port", port); this.jmdns.registerService(service); // Set it again, this time for the lock below this.timeOfStartup = System.currentTimeMillis(); } catch (final IOException e) { e.printStackTrace(); } catch (final IllegalStateException e) { this.logger.status("backgroundinit/exception/illegalstate", "message", e.getMessage()); } finally { this.logger.status("backgroundinit/unlock"); this.startupLatch.countDown(); this.jmdnsLock.unlock(); } this.logger.status("backgroundinit/end"); }
/** @{inheritDoc} */ public void unregisterService(ServiceDescription description) { ServiceInfo serviceInfo = ServiceInfo.create( description.serviceType, description.serviceName, description.servicePort, 0, 0, description.serviceProperties); logger.debug( "Unregistering service " + description.serviceType + " at port " + String.valueOf(description.servicePort)); jmdns.unregisterService(serviceInfo); }
@Override public void createService(String name, String type, int port) { if (!type.contains(TYPE_PADDING)) { type = type + TYPE_PADDING; } mType = type; acquireMulticastLock(); try { if (null != mJmDNS) { destroyService(null, false); } if (mHost) { mJmDNS = JmDNS.create(mWifiEnable); } else { if (null != mAddress) { mJmDNS = JmDNS.create(mAddress, name); } else { mJmDNS = JmDNS.create(mWifiEnable); } } } catch (Exception e) { Log.e(TAG, "failed to create the service", e); if (null != mServiceListener) { mServiceListener.onServiceRegisteredFailed(new ZeroServiceInfo(null, null)); } } if (null != mJmDNS) { try { ServiceInfo si = ServiceInfo.create( mType, name, port, LOCAL_SERVER_WEIGHT, LOCAL_SERVER_PROIORITY, true, "android_jmdns_service"); mJmDNS.registerService(si); } catch (Exception e) { Log.e(TAG, "failed to cast the service", e); } } }
/** * Create a ZeroConfService. The property <i>version</i> is added or replaced with the current * JMRI version as its value. The property <i>jmri</i> is added or replaced with the JMRI * major.minor.test version string as its value. * * <p>If a service with the same key as the new service is already published, the original service * is returned unmodified. * * @param type The service protocol * @param name The name of the JMRI server listed on client devices * @param port The port the service runs over * @param weight Default value is 0 * @param priority Default value is 0 * @param properties Additional information to be listed in service advertisement * @return An unpublished ZeroConfService */ public static ZeroConfService create( String type, String name, int port, int weight, int priority, HashMap<String, String> properties) { ZeroConfService s; if (ZeroConfService.services().containsKey(ZeroConfService.key(type, name))) { s = ZeroConfService.services().get(ZeroConfService.key(type, name)); log.debug("Using existing ZeroConfService {}", s.key()); } else { properties.put("version", jmri.Version.name()); // use the major.minor.test version string for jmri since we have potentially // tight space constraints in terms of the number of bytes that properties // can use, and there are some unconstrained properties that we would like to use. properties.put("jmri", jmri.Version.getCanonicalVersion()); properties.put("node", NodeIdentity.identity()); s = new ZeroConfService(ServiceInfo.create(type, name, port, weight, priority, properties)); log.debug("Creating new ZeroConfService {} with properties {}", s.key(), properties); } return s; }
@Override public PluginResult execute(String action, JSONArray data, String callbackId) { // Log.d("OSCManager", "executing something " + action); PluginResult result = null; try { System.out.println("EXECUTING BONJOUR ********************************************"); if (action.equals("start") || action.equals("browse")) { System.out.println("STARTING BONJOUR ********************************************"); ServiceInfo[] infos = jmdns.list("_osc._udp.local."); for (int i = 0; i < infos.length; i++) { String jsString = "javascript:destinationManager.addDestination('" + infos[i].getHostAddress() + "'," + infos[i].getPort() + ", 0, 0);"; System.out.println(jsString); webView.loadUrl(jsString); System.out.println("after sending to js"); } if (action.equals("start")) { ServiceInfo serviceInfo = ServiceInfo.create( "_osc._udp.local.", "Control_" + (Math.round(Math.random() * 100000)), 8080, "OSC reception for device running Control"); jmdns.registerService(serviceInfo); } } } catch (Exception e) { System.out.println("after sending to js"); } return result; }
@Override public void run() { try { final JmDNS jmdns = JmDNS.create(); jmdns.addServiceListener(TOUCH_ABLE_TYPE, this); jmdns.addServiceListener(DACP_TYPE, this); final HashMap<String, String> values = new HashMap<String, String>(); byte[] number = new byte[4]; random.nextBytes(number); values.put("DvNm", "Android-" + toHex(number)); values.put("RemV", "10000"); values.put("DvTy", "iPod"); values.put("RemN", "Remote"); values.put("txtvers", "1"); byte[] pair = new byte[8]; random.nextBytes(pair); values.put("Pair", toHex(pair)); while (_running) { ServerSocket server = new ServerSocket(0); byte[] name = new byte[20]; random.nextBytes(name); System.out.println("Requesting pairing for " + toHex(name)); ServiceInfo pairservice = ServiceInfo.create(REMOTE_TYPE, toHex(name), server.getLocalPort(), 0, 0, values); jmdns.registerService(pairservice); System.out.println("Waiting for pass code"); final Socket socket = server.accept(); OutputStream output = null; try { output = socket.getOutputStream(); // output the contents for debugging final BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (br.ready()) { String line = br.readLine(); System.out.println(line); } // edit our local PAIRING_RAW to return the correct guid byte[] code = new byte[8]; random.nextBytes(code); System.out.println("Device guid: " + toHex(code)); System.arraycopy(code, 0, PAIRING_RAW, 16, 8); byte[] header = String.format( "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n", new Integer(PAIRING_RAW.length)) .getBytes(); byte[] reply = new byte[header.length + PAIRING_RAW.length]; System.arraycopy(header, 0, reply, 0, header.length); System.arraycopy(PAIRING_RAW, 0, reply, header.length, PAIRING_RAW.length); System.out.println("Response: " + new String(reply)); output.write(reply); output.flush(); System.out.println("someone paired with me!"); jmdns.unregisterService(pairservice); } finally { if (output != null) { output.close(); } System.out.println("Closing Socket"); if (!server.isClosed()) { server.close(); } _running = false; } } Thread.sleep(6000); System.out.println("Closing JmDNS"); jmdns.close(); } catch (Exception e) { e.printStackTrace(); } }
public static void main(final String[] args) throws Exception { /* Make sure AirReceiver shuts down gracefully */ Runtime.getRuntime() .addShutdownHook( new Thread( new Runnable() { @Override public void run() { onShutdown(); } })); /* Create about dialog */ final Dialog aboutDialog = new Dialog((Dialog) null); final GridBagLayout aboutLayout = new GridBagLayout(); aboutDialog.setLayout(aboutLayout); aboutDialog.setVisible(false); aboutDialog.setTitle("About AirReceiver"); aboutDialog.setResizable(false); { /* Message */ final TextArea title = new TextArea(AboutMessage.split("\n").length + 1, 64); title.setText(AboutMessage); title.setEditable(false); final GridBagConstraints titleConstraints = new GridBagConstraints(); titleConstraints.gridx = 1; titleConstraints.gridy = 1; titleConstraints.fill = GridBagConstraints.HORIZONTAL; titleConstraints.insets = new Insets(0, 0, 0, 0); aboutLayout.setConstraints(title, titleConstraints); aboutDialog.add(title); } { /* Done button */ final Button aboutDoneButton = new Button("Done"); aboutDoneButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { aboutDialog.setVisible(false); } }); final GridBagConstraints aboutDoneConstraints = new GridBagConstraints(); aboutDoneConstraints.gridx = 1; aboutDoneConstraints.gridy = 2; aboutDoneConstraints.anchor = GridBagConstraints.PAGE_END; aboutDoneConstraints.fill = GridBagConstraints.NONE; aboutDoneConstraints.insets = new Insets(0, 0, 0, 0); aboutLayout.setConstraints(aboutDoneButton, aboutDoneConstraints); aboutDialog.add(aboutDoneButton); } aboutDialog.setVisible(false); aboutDialog.setLocationByPlatform(true); aboutDialog.pack(); /* Create tray icon */ final URL trayIconUrl = AirReceiver.class.getClassLoader().getResource("icon_32.png"); final TrayIcon trayIcon = new TrayIcon((new ImageIcon(trayIconUrl, "AirReceiver").getImage())); trayIcon.setToolTip("AirReceiver"); trayIcon.setImageAutoSize(true); final PopupMenu popupMenu = new PopupMenu(); final MenuItem aboutMenuItem = new MenuItem("About"); aboutMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { aboutDialog.setLocationByPlatform(true); aboutDialog.setVisible(true); } }); popupMenu.add(aboutMenuItem); final MenuItem exitMenuItem = new MenuItem("Quit"); exitMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { onShutdown(); System.exit(0); } }); popupMenu.add(exitMenuItem); trayIcon.setPopupMenu(popupMenu); SystemTray.getSystemTray().add(trayIcon); /* Create AirTunes RTSP server */ final ServerBootstrap airTunesRtspBootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(ExecutorService, ExecutorService)); airTunesRtspBootstrap.setPipelineFactory(new RaopRtspPipelineFactory()); airTunesRtspBootstrap.setOption("reuseAddress", true); airTunesRtspBootstrap.setOption("child.tcpNoDelay", true); airTunesRtspBootstrap.setOption("child.keepAlive", true); s_allChannels.add( airTunesRtspBootstrap.bind( new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), AirtunesServiceRTSPPort))); s_logger.info("Launched RTSP service on port " + AirtunesServiceRTSPPort); /* Create mDNS responders. */ synchronized (s_jmDNSInstances) { for (final NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) { if (iface.isLoopback()) continue; if (iface.isPointToPoint()) continue; if (!iface.isUp()) continue; for (final InetAddress addr : Collections.list(iface.getInetAddresses())) { if (!(addr instanceof Inet4Address) && !(addr instanceof Inet6Address)) continue; try { /* Create mDNS responder for address */ final JmDNS jmDNS = JmDNS.create(addr, HostName + "-jmdns"); s_jmDNSInstances.add(jmDNS); /* Publish RAOP service */ final ServiceInfo airTunesServiceInfo = ServiceInfo.create( AirtunesServiceType, HardwareAddressString + "@" + HostName + " (" + iface.getName() + ")", AirtunesServiceRTSPPort, 0 /* weight */, 0 /* priority */, AirtunesServiceProperties); jmDNS.registerService(airTunesServiceInfo); s_logger.info( "Registered AirTunes service '" + airTunesServiceInfo.getName() + "' on " + addr); } catch (final Throwable e) { s_logger.log(Level.SEVERE, "Failed to publish service on " + addr, e); } } } } }