public TRTrackerServerUDP(String _name, int _port, boolean _start_up_ready) {
    super(_name, _start_up_ready);

    port = _port;

    thread_pool = new ThreadPool("TrackerServer:UDP:" + port, THREAD_POOL_SIZE);

    try {
      InetAddress bind_ip = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress();

      InetSocketAddress address;

      DatagramSocket socket;

      if (bind_ip == null) {

        address = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), port);

        socket = new DatagramSocket(port);

      } else {

        current_bind_ip = bind_ip;

        address = new InetSocketAddress(bind_ip, port);

        socket = new DatagramSocket(address);
      }

      socket.setReuseAddress(true);

      dg_socket = socket;

      final InetSocketAddress f_address = address;

      Thread recv_thread =
          new AEThread("TRTrackerServerUDP:recv.loop") {
            public void runSupport() {
              recvLoop(dg_socket, f_address);
            }
          };

      recv_thread.setDaemon(true);

      recv_thread.start();

      Logger.log(new LogEvent(LOGID, "TRTrackerServerUDP: recv established on port " + port));

    } catch (Throwable e) {

      Logger.log(
          new LogEvent(
              LOGID, "TRTrackerServerUDP: " + "DatagramSocket bind failed on port " + port, e));
    }
  }
  /**
   * Perform the actual version check by connecting to the version server.
   *
   * @param data_to_send version message
   * @return version reply
   * @throws Exception if the server check connection fails
   */
  private Map performVersionCheck(
      Map data_to_send, boolean use_az_message, boolean use_http, boolean v6) throws Exception {
    Exception error = null;
    Map reply = null;

    if (use_http) {

      try {
        reply = executeHTTP(data_to_send, v6);

        reply.put("protocol_used", "HTTP");

        error = null;
      } catch (IOException e) {
        error = e;
      } catch (Exception e) {
        Debug.printStackTrace(e);
        error = e;
      }
    }

    if (reply == null && use_az_message) {

      try {
        reply = executeAZMessage(data_to_send, v6);

        reply.put("protocol_used", "AZMSG");
      } catch (IOException e) {
        error = e;
      } catch (Exception e) {
        Debug.printStackTrace(e);
        error = e;
      }
    }
    if (error != null) {

      throw (error);
    }

    if (Logger.isEnabled())
      Logger.log(
          new LogEvent(
              LOGID,
              "VersionCheckClient server "
                  + "version check successful. Received "
                  + reply.size()
                  + " reply keys."));

    if (v6) {

      last_check_time_v6 = SystemTime.getCurrentTime();

    } else {

      last_check_time_v4 = SystemTime.getCurrentTime();
    }

    return reply;
  }
  /** Start the server and begin accepting incoming connections. */
  public void start() {
    try {
      this_mon.enter();

      if (!isRunning()) {
        try {
          server_channel = ServerSocketChannel.open();

          server_channel.socket().setReuseAddress(true);
          if (receive_buffer_size > 0)
            server_channel.socket().setReceiveBufferSize(receive_buffer_size);

          server_channel.socket().bind(bind_address, 1024);

          if (Logger.isEnabled())
            Logger.log(new LogEvent(LOGID, "TCP incoming server socket " + bind_address));

          AEThread accept_thread =
              new AEThread("VServerSelector:port" + bind_address.getPort()) {
                public void runSupport() {
                  accept_loop();
                }
              };
          accept_thread.setDaemon(true);
          accept_thread.start();
        } catch (Throwable t) {
          Debug.out(t);
          Logger.log(
              new LogAlert(
                  LogAlert.UNREPEATABLE,
                  "ERROR, unable to bind TCP incoming server socket to " + bind_address.getPort(),
                  t));
        }

        last_accept_time = SystemTime.getCurrentTime(); // init to now
      }
    } finally {

      this_mon.exit();
    }
  }
  private Map executeHTTP(Map data_to_send, boolean v6) throws Exception {

    if (v6 && !enable_v6) {

      throw (new Exception("IPv6 is disabled"));
    }

    String host = getHost(v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4);

    if (Logger.isEnabled())
      Logger.log(
          new LogEvent(
              LOGID,
              "VersionCheckClient retrieving "
                  + "version information from "
                  + host
                  + ":"
                  + HTTP_SERVER_PORT
                  + " via HTTP"));

    String url_str =
        "http://"
            + (v6 ? UrlUtils.convertIPV6Host(host) : host)
            + (HTTP_SERVER_PORT == 80 ? "" : (":" + HTTP_SERVER_PORT))
            + "/version?";

    url_str +=
        URLEncoder.encode(new String(BEncoder.encode(data_to_send), "ISO-8859-1"), "ISO-8859-1");

    URL url = new URL(url_str);

    HttpURLConnection url_connection = (HttpURLConnection) url.openConnection();

    url_connection.connect();

    try {
      InputStream is = url_connection.getInputStream();

      Map reply = BDecoder.decode(new BufferedInputStream(is));

      preProcessReply(reply, v6);

      return (reply);

    } finally {

      url_connection.disconnect();
    }
  }
  protected void recvLoop(DatagramSocket socket, InetSocketAddress address) {
    long successful_accepts = 0;
    long failed_accepts = 0;

    while (!closed) {

      try {
        byte[] buf = new byte[PRUDPPacket.MAX_PACKET_SIZE];

        DatagramPacket packet = new DatagramPacket(buf, buf.length, address);

        socket.receive(packet);

        successful_accepts++;

        failed_accepts = 0;

        String ip = packet.getAddress().getHostAddress();

        if (!ip_filter.isInRange(ip, "Tracker", null)) {

          thread_pool.run(new TRTrackerServerProcessorUDP(this, socket, packet));
        }

      } catch (Throwable e) {

        if (!closed) {

          failed_accepts++;

          Logger.log(new LogEvent(LOGID, "TRTrackerServer: receive failed on port " + port, e));

          if ((failed_accepts > 100 && successful_accepts == 0) || failed_accepts > 1000) {

            // looks like its not going to work...
            // some kind of socket problem

            Logger.logTextResource(
                new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Network.alert.acceptfail"),
                new String[] {"" + port, "UDP"});

            break;
          }
        }
      }
    }
  }
  private Map executeAZMessage(Map data_to_send, boolean v6) throws Exception {

    if (v6 && !enable_v6) {

      throw (new Exception("IPv6 is disabled"));
    }

    String host = getHost(v6, AZ_MSG_SERVER_ADDRESS_V6, AZ_MSG_SERVER_ADDRESS_V4);

    if (Logger.isEnabled())
      Logger.log(
          new LogEvent(
              LOGID,
              "VersionCheckClient retrieving "
                  + "version information from "
                  + host
                  + ":"
                  + AZ_MSG_SERVER_PORT));

    ClientMessageService msg_service = null;
    Map reply = null;

    try {
      msg_service =
          ClientMessageServiceClient.getServerService(host, AZ_MSG_SERVER_PORT, MESSAGE_TYPE_ID);

      msg_service.sendMessage(data_to_send); // send our version message

      reply = msg_service.receiveMessage(); // get the server reply

      preProcessReply(reply, v6);

    } finally {

      if (msg_service != null) {

        msg_service.close();
      }
    }

    return (reply);
  }
Example #7
0
  protected void activityFinished(boolean download, String item_name, Object relatedObject) {
    final String sound_enabler;
    final String sound_file;
    final String default_sound = "org/gudy/azureus2/ui/icons/downloadFinished.wav";

    final String speech_enabler;
    final String speech_text;

    final String popup_enabler;
    final String popup_def_text;

    if (download) {
      sound_enabler = "Play Download Finished";
      sound_file = "Play Download Finished File";

      speech_enabler = "Play Download Finished Announcement";
      speech_text = "Play Download Finished Announcement Text";

      popup_enabler = "Popup Download Finished";
      popup_def_text = "popup.download.finished";

    } else {
      sound_enabler = "Play File Finished";
      sound_file = "Play File Finished File";

      speech_enabler = "Play File Finished Announcement";
      speech_text = "Play File Finished Announcement Text";

      popup_enabler = "Popup File Finished";
      popup_def_text = "popup.file.finished";
    }

    try {
      this_mon.enter();

      if (COConfigurationManager.getBooleanParameter(popup_enabler)) {
        String popup_text = MessageText.getString(popup_def_text, new String[] {item_name});
        Logger.log(new LogAlert(relatedObject, true, LogAlert.AT_INFORMATION, popup_text));
      }

      if (Constants.isOSX) { // OS X cannot concurrently use SWT and AWT
        new AEThread("DownloadSound") {
          public void runSupport() {
            try {
              if (COConfigurationManager.getBooleanParameter(speech_enabler))
                Runtime.getRuntime()
                    .exec(
                        new String[] {
                          "say", COConfigurationManager.getStringParameter(speech_text)
                        }); // Speech Synthesis services

              if (COConfigurationManager.getBooleanParameter(sound_enabler))
                Runtime.getRuntime()
                    .exec(
                        new String[] {
                          "osascript", "-e", "beep"
                        }); // Beep alert type is in accordance with System Preferences

              Thread.sleep(2500);
            } catch (Throwable e) {
            }
          }
        }.start();
      } else if (COConfigurationManager.getBooleanParameter(sound_enabler, false)) {

        String file = COConfigurationManager.getStringParameter(sound_file);

        file = file.trim();

        // turn "<default>" into blank

        if (file.startsWith("<")) {

          file = "";
        }

        if (audio_clip == null || !file.equals(audio_resource)) {

          audio_clip = null;

          // try explicit file

          if (file.length() != 0) {

            File f = new File(file);

            try {

              if (f.exists()) {

                URL file_url = f.toURL();

                audio_clip = Applet.newAudioClip(file_url);
              }

            } catch (Throwable e) {

              Debug.printStackTrace(e);

            } finally {

              if (audio_clip == null) {
                Logger.log(
                    new LogAlert(
                        relatedObject,
                        LogAlert.UNREPEATABLE,
                        LogAlert.AT_ERROR,
                        "Failed to load audio file '" + file + "'"));
              }
            }
          }

          // either non-explicit or explicit missing

          if (audio_clip == null) {

            audio_clip =
                Applet.newAudioClip(UserAlerts.class.getClassLoader().getResource(default_sound));
          }

          audio_resource = file;
        }

        if (audio_clip != null) {

          new AEThread("DownloadSound") {
            public void runSupport() {
              try {
                audio_clip.play();

                Thread.sleep(2500);

              } catch (Throwable e) {

              }
            }
          }.start();
        }
      }
    } catch (Throwable e) {

      Debug.printStackTrace(e);

    } finally {

      this_mon.exit();
    }
  }
  public void runSupport() {
    byte[] input_buffer = new byte[request_dg.getLength()];

    System.arraycopy(request_dg.getData(), 0, input_buffer, 0, input_buffer.length);

    int packet_data_length = input_buffer.length;

    String auth_user = null;
    byte[] auth_user_bytes = null;
    byte[] auth_hash = null;

    if (server.isTrackerPasswordEnabled()) {

      // auth detail should be attached to the packet. Auth details are 16
      // bytes

      if (input_buffer.length < 17) {

        Logger.log(
            new LogEvent(
                LOGID,
                LogEvent.LT_WARNING,
                "TRTrackerServerProcessorUDP: " + "packet received but authorisation missing"));

        return;
      }

      packet_data_length -= 16;

      auth_user_bytes = new byte[8];

      auth_hash = new byte[8];

      System.arraycopy(input_buffer, packet_data_length, auth_user_bytes, 0, 8);

      int user_len = 0;

      while (user_len < 8 && auth_user_bytes[user_len] != 0) {

        user_len++;
      }

      auth_user = new String(auth_user_bytes, 0, user_len);

      System.arraycopy(input_buffer, packet_data_length + 8, auth_hash, 0, 8);
    }

    DataInputStream is =
        new DataInputStream(new ByteArrayInputStream(input_buffer, 0, packet_data_length));

    try {
      String client_ip_address = request_dg.getAddress().getHostAddress();

      PRUDPPacketRequest request = PRUDPPacketRequest.deserialiseRequest(null, is);

      Logger.log(
          new LogEvent(
              LOGID, "TRTrackerServerProcessorUDP: packet received: " + request.getString()));

      PRUDPPacket reply = null;
      TRTrackerServerTorrentImpl torrent = null;

      if (auth_user_bytes != null) {

        // user name is irrelevant as we only have one at the moment

        // <parg_home> so <new_packet> = <old_packet> + <user_padded_to_8_bytes> + <hash>
        // <parg_home> where <hash> = first 8 bytes of sha1(<old_packet> + <user_padded_to_8> +
        // sha1(pass))
        // <XTF> Yes

        byte[] sha1_pw = null;

        if (server.hasExternalAuthorisation()) {

          try {
            URL resource = new URL("udp://" + server.getHost() + ":" + server.getPort() + "/");

            sha1_pw = server.performExternalAuthorisation(resource, auth_user);

          } catch (MalformedURLException e) {

            Debug.printStackTrace(e);
          }

          if (sha1_pw == null) {

            Logger.log(
                new LogEvent(
                    LOGID,
                    LogEvent.LT_ERROR,
                    "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));

            reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");
          }
        } else {

          sha1_pw = server.getPassword();
        }

        // if we haven't already failed then check the PW

        if (reply == null) {

          SHA1Hasher hasher = new SHA1Hasher();

          hasher.update(input_buffer, 0, packet_data_length);
          hasher.update(auth_user_bytes);
          hasher.update(sha1_pw);

          byte[] digest = hasher.getDigest();

          for (int i = 0; i < auth_hash.length; i++) {

            if (auth_hash[i] != digest[i]) {

              Logger.log(
                  new LogEvent(
                      LOGID,
                      LogEvent.LT_ERROR,
                      "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));

              reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");

              break;
            }
          }
        }
      }

      int request_type = TRTrackerServerRequest.RT_UNKNOWN;

      if (reply == null) {

        if (server.isEnabled()) {

          try {
            int type = request.getAction();

            if (type == PRUDPPacketTracker.ACT_REQUEST_CONNECT) {

              reply = handleConnect(client_ip_address, request);

            } else if (type == PRUDPPacketTracker.ACT_REQUEST_ANNOUNCE) {

              Object[] x =
                  handleAnnounceAndScrape(
                      client_ip_address, request, TRTrackerServerRequest.RT_ANNOUNCE);

              if (x == null) {

                throw (new Exception("Connection ID mismatch"));
              }

              reply = (PRUDPPacket) x[0];
              torrent = (TRTrackerServerTorrentImpl) x[1];

              request_type = TRTrackerServerRequest.RT_ANNOUNCE;

            } else if (type == PRUDPPacketTracker.ACT_REQUEST_SCRAPE) {

              Object[] x =
                  handleAnnounceAndScrape(
                      client_ip_address, request, TRTrackerServerRequest.RT_SCRAPE);

              if (x == null) {

                throw (new Exception("Connection ID mismatch"));
              }

              reply = (PRUDPPacket) x[0];
              torrent = (TRTrackerServerTorrentImpl) x[1];

              request_type = TRTrackerServerRequest.RT_SCRAPE;

            } else {

              reply = new PRUDPPacketReplyError(request.getTransactionId(), "unsupported action");
            }
          } catch (Throwable e) {

            // e.printStackTrace();

            String error = e.getMessage();

            if (error == null) {

              error = e.toString();
            }

            reply = new PRUDPPacketReplyError(request.getTransactionId(), error);
          }
        } else {

          System.out.println("UDP Tracker: replying 'disabled' to " + client_ip_address);

          reply = new PRUDPPacketReplyError(request.getTransactionId(), "UDP Tracker disabled");
        }
      }

      if (reply != null) {

        InetAddress address = request_dg.getAddress();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        DataOutputStream os = new DataOutputStream(baos);

        reply.serialise(os);

        byte[] output_buffer = baos.toByteArray();

        DatagramPacket reply_packet =
            new DatagramPacket(output_buffer, output_buffer.length, address, request_dg.getPort());

        socket.send(reply_packet);

        server.updateStats(request_type, torrent, input_buffer.length, output_buffer.length);
      }

    } catch (Throwable e) {

      Logger.log(new LogEvent(LOGID, "TRTrackerServerProcessorUDP: processing fails", e));
    } finally {

      try {
        is.close();

      } catch (Throwable e) {

      }
    }
  }
  private Map executeTCP(Map data_to_send, InetAddress bind_ip, int bind_port, boolean v6)
      throws Exception {
    if (v6 && !enable_v6) {

      throw (new Exception("IPv6 is disabled"));
    }

    String host = getHost(v6, TCP_SERVER_ADDRESS_V6, TCP_SERVER_ADDRESS_V4);

    if (Logger.isEnabled())
      Logger.log(
          new LogEvent(
              LOGID,
              "VersionCheckClient retrieving "
                  + "version information from "
                  + host
                  + ":"
                  + TCP_SERVER_PORT
                  + " via TCP"));

    String get_str = getHTTPGetString(data_to_send, false, v6);

    Socket socket = null;

    try {
      socket = new Socket();

      if (bind_ip != null) {

        socket.bind(new InetSocketAddress(bind_ip, bind_port));

      } else if (bind_port != 0) {

        socket.bind(new InetSocketAddress(bind_port));
      }

      socket.setSoTimeout(10000);

      socket.connect(new InetSocketAddress(host, TCP_SERVER_PORT), 10000);

      OutputStream os = socket.getOutputStream();

      os.write(get_str.getBytes("ISO-8859-1"));

      os.flush();

      InputStream is = socket.getInputStream();

      byte[] buffer = new byte[1];

      String header = "";

      int content_length = -1;

      while (true) {

        int len = is.read(buffer);

        if (len <= 0) {

          break;
        }

        header += (char) buffer[0];

        if (header.endsWith("\r\n\r\n")) {

          header = header.toLowerCase(MessageText.LOCALE_ENGLISH);

          int pos = header.indexOf("content-length:");

          if (pos == -1) {

            throw (new IOException("content length missing"));
          }

          header = header.substring(pos + 15);

          pos = header.indexOf('\r');

          header = header.substring(0, pos).trim();

          content_length = Integer.parseInt(header);

          if (content_length > 10000) {

            throw (new IOException("content length too large"));
          }

          break;
        }

        if (header.length() > 2048) {

          throw (new IOException("header too large"));
        }
      }

      ByteArrayOutputStream baos = new ByteArrayOutputStream(content_length);

      buffer = new byte[content_length];

      while (content_length > 0) {

        int len = is.read(buffer);

        if (len <= 0) {

          break;
        }

        baos.write(buffer, 0, len);

        content_length -= len;
      }

      if (content_length != 0) {

        throw (new IOException("error reading reply"));
      }

      byte[] reply_bytes = baos.toByteArray();

      Map reply = BDecoder.decode(new BufferedInputStream(new ByteArrayInputStream(reply_bytes)));

      preProcessReply(reply, v6);

      return (reply);

    } finally {

      if (socket != null) {

        try {
          socket.close();

        } catch (Throwable e) {

        }
      }
    }
  }
  protected Map getVersionCheckInfoSupport(
      String reason, boolean only_if_cached, boolean force, boolean v6) {
    try {
      synchronized (listeners) {
        if (REASON_UPDATE_CHECK_START.equals(reason)) {
          startCheckRan = true;
        }
        for (VersionCheckClientListener l : listeners) {
          l.versionCheckStarted(reason);
        }
      }
    } catch (Throwable t) {
      Debug.out(t);
    }
    if (v6) {

      if (enable_v6) {

        try {
          check_mon.enter();

          long time_diff = SystemTime.getCurrentTime() - last_check_time_v6;

          force = force || time_diff > CACHE_PERIOD || time_diff < 0;

          if (last_check_data_v6 == null || last_check_data_v6.size() == 0 || force) {
            // if we've never checked before then we go ahead even if the "only_if_cached"
            // flag is set as its had not chance of being cached yet!
            if (only_if_cached && last_check_data_v6 != null) {
              return (new HashMap());
            }
            try {
              last_check_data_v6 =
                  performVersionCheck(constructVersionCheckMessage(reason), true, true, true);

              if (last_check_data_v6 != null && last_check_data_v6.size() > 0) {

                COConfigurationManager.setParameter("versioncheck.cache.v6", last_check_data_v6);
              }
            } catch (SocketException t) {
              // internet is broken
              // Debug.out(t.getClass().getName() + ": " + t.getMessage());
            } catch (UnknownHostException t) {
              // dns is broken
              // Debug.out(t.getClass().getName() + ": " + t.getMessage());
            } catch (Throwable t) {
              Debug.out(t);
              last_check_data_v6 = new HashMap();
            }
          } else {
            Logger.log(
                new LogEvent(
                    LOGID,
                    "VersionCheckClient is using "
                        + "cached version check info. Using "
                        + last_check_data_v6.size()
                        + " reply keys."));
          }
        } finally {
          check_mon.exit();
        }
      }

      if (last_check_data_v6 == null) last_check_data_v6 = new HashMap();

      return last_check_data_v6;

    } else {

      try {
        check_mon.enter();

        long time_diff = SystemTime.getCurrentTime() - last_check_time_v4;

        force = force || time_diff > CACHE_PERIOD || time_diff < 0;

        if (last_check_data_v4 == null || last_check_data_v4.size() == 0 || force) {
          // if we've never checked before then we go ahead even if the "only_if_cached"
          // flag is set as its had not chance of being cached yet!
          if (only_if_cached && last_check_data_v4 != null) {
            return (new HashMap());
          }
          try {
            last_check_data_v4 =
                performVersionCheck(constructVersionCheckMessage(reason), true, true, false);

            if (last_check_data_v4 != null && last_check_data_v4.size() > 0) {

              COConfigurationManager.setParameter("versioncheck.cache.v4", last_check_data_v4);
            }

            // clear down any plugin-specific data that has successfully been sent to the version
            // server

            try {
              if (AzureusCoreFactory.isCoreAvailable()) {

                // installed plugin IDs
                PluginInterface[] plugins =
                    AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaces();

                for (int i = 0; i < plugins.length; i++) {

                  PluginInterface plugin = plugins[i];

                  Map data =
                      plugin
                          .getPluginconfig()
                          .getPluginMapParameter("plugin.versionserver.data", null);

                  if (data != null) {

                    plugin
                        .getPluginconfig()
                        .setPluginMapParameter("plugin.versionserver.data", new HashMap());
                  }
                }
              }
            } catch (Throwable e) {
            }
          } catch (UnknownHostException t) {
            // no internet
            Debug.outNoStack(
                "VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
          } catch (IOException t) {
            // General connection problem.
            Debug.outNoStack(
                "VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
          } catch (Throwable t) {
            Debug.out(t);
            last_check_data_v4 = new HashMap();
          }
        } else {
          if (Logger.isEnabled())
            Logger.log(
                new LogEvent(
                    LOGID,
                    "VersionCheckClient is using "
                        + "cached version check info. Using "
                        + last_check_data_v4.size()
                        + " reply keys."));
        }
      } finally {
        check_mon.exit();
      }

      if (last_check_data_v4 == null) last_check_data_v4 = new HashMap();

      last_feature_flag_cache_time = 0;

      return last_check_data_v4;
    }
  }
  protected void preProcessReply(Map reply, final boolean v6) {
    NetworkAdmin admin = NetworkAdmin.getSingleton();

    try {
      byte[] address = (byte[]) reply.get("source_ip_address");

      InetAddress my_ip = InetAddress.getByName(new String(address));

      NetworkAdminASN old_asn = admin.getCurrentASN();

      NetworkAdminASN new_asn = admin.lookupCurrentASN(my_ip);

      if (!new_asn.sameAs(old_asn)) {

        // kick off a secondary version check to communicate the new information

        if (!secondary_check_done) {

          secondary_check_done = true;

          new AEThread("Secondary version check", true) {
            public void runSupport() {
              getVersionCheckInfoSupport(REASON_SECONDARY_CHECK, false, true, v6);
            }
          }.start();
        }
      }
    } catch (Throwable e) {

      Debug.printStackTrace(e);
    }

    Long as_advice = (Long) reply.get("as_advice");

    if (as_advice != null) {

      NetworkAdminASN current_asn = admin.getCurrentASN();

      String asn = current_asn.getASName();

      if (asn != null) {

        long advice = as_advice.longValue();

        if (advice != 0) {

          // require crypto

          String done_asn = COConfigurationManager.getStringParameter("ASN Advice Followed", "");

          if (!done_asn.equals(asn)) {

            COConfigurationManager.setParameter("ASN Advice Followed", asn);

            boolean change = advice == 1 || advice == 2;
            boolean alert = advice == 1 || advice == 3;

            if (!COConfigurationManager.getBooleanParameter(
                "network.transport.encrypted.require")) {

              if (change) {

                COConfigurationManager.setParameter("network.transport.encrypted.require", true);
              }

              if (alert) {

                String msg = MessageText.getString("crypto.alert.as.warning", new String[] {asn});

                Logger.log(new LogAlert(false, LogAlert.AT_WARNING, msg));
              }
            }
          }
        }
      }
    }

    // set ui.toolbar.uiswitcher based on instructions from tracker
    // Really shouldn't be in VersionCheck client, but instead have some
    // listener and have the code elsewhere.  Simply calling
    // getVersionCheckInfo from "code elsewhere" (to get the cached result)
    // caused a deadlock at startup.
    Long lEnabledUISwitcher = (Long) reply.get("ui.toolbar.uiswitcher");
    if (lEnabledUISwitcher != null) {
      COConfigurationManager.setBooleanDefault(
          "ui.toolbar.uiswitcher", lEnabledUISwitcher.longValue() == 1);
    }
  }