public Map<String, Object> getCountryInfo() {
    Map reply = getVersionCheckInfo(REASON_EXTERNAL_IP, AT_EITHER);

    Map<String, Object> info = (Map<String, Object>) reply.get("source_info");

    if (info == null) {

      return (new HashMap<String, Object>());

    } else {

      return (BDecoder.decodeStrings(info));
    }
  }
  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();
    }
  }
  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) {

        }
      }
    }
  }