/**
   * Initializes and binds a socket that on a random port number. The method would try to bind on a
   * random port and retry 5 times until a free port is found.
   *
   * @return the socket that we have initialized on a randomport number.
   */
  private DatagramSocket initRandomPortSocket() {
    DatagramSocket resultSocket = null;
    String bindRetriesStr =
        NetaddrActivator.getConfigurationService().getString(BIND_RETRIES_PROPERTY_NAME);

    int bindRetries = 5;

    if (bindRetriesStr != null) {
      try {
        bindRetries = Integer.parseInt(bindRetriesStr);
      } catch (NumberFormatException ex) {
        logger.error(
            bindRetriesStr
                + " does not appear to be an integer. "
                + "Defaulting port bind retries to "
                + bindRetries,
            ex);
      }
    }

    int currentlyTriedPort = NetworkUtils.getRandomPortNumber();

    // we'll first try to bind to a random port. if this fails we'll try
    // again (bindRetries times in all) until we find a free local port.
    for (int i = 0; i < bindRetries; i++) {
      try {
        resultSocket = new DatagramSocket(currentlyTriedPort);
        // we succeeded - break so that we don't try to bind again
        break;
      } catch (SocketException exc) {
        if (exc.getMessage().indexOf("Address already in use") == -1) {
          logger.fatal(
              "An exception occurred while trying to create" + "a local host discovery socket.",
              exc);
          resultSocket = null;
          return null;
        }
        // port seems to be taken. try another one.
        logger.debug("Port " + currentlyTriedPort + " seems in use.");
        currentlyTriedPort = NetworkUtils.getRandomPortNumber();
        logger.debug("Retrying bind on port " + currentlyTriedPort);
      }
    }

    return resultSocket;
  }
Пример #2
0
  /**
   * Sends local candidate addresses from the local peer to the remote peer using the
   * <tt>candidates</tt> {@link SessionIQ}.
   *
   * @param candidates the local candidate addresses to be sent from the local peer to the remote
   *     peer using the <tt>candidates</tt> {@link SessionIQ}
   */
  protected void sendCandidates(Iterable<GTalkCandidatePacketExtension> candidates) {
    ProtocolProviderServiceJabberImpl protocolProvider = getProtocolProvider();

    SessionIQ candidatesIQ = new SessionIQ();

    candidatesIQ.setGTalkType(GTalkType.CANDIDATES);
    candidatesIQ.setFrom(protocolProvider.getOurJID());
    candidatesIQ.setInitiator(isInitiator() ? getAddress() : protocolProvider.getOurJID());
    candidatesIQ.setID(getSID());
    candidatesIQ.setTo(getAddress());
    candidatesIQ.setType(IQ.Type.SET);

    for (GTalkCandidatePacketExtension candidate : candidates) {
      // Android phone and Google Talk client does not seems to like IPv6
      // candidates since it reject the IQ candidates with an error
      // so do not send IPv6 candidates to Android phone or Talk client
      if (isAndroidOrVtokOrTalkClient(getAddress())
          && NetworkUtils.isIPv6Address(candidate.getAddress())) continue;

      candidatesIQ.addExtension(candidate);
    }

    protocolProvider.getConnection().sendPacket(candidatesIQ);
  }
  /**
   * Returns the Google Contacts connection.
   *
   * @return Google Contacts connection
   */
  public GoogleContactsConnectionImpl getConnection() {
    int s = login.indexOf('@');
    boolean isGoogleAppsOrGmail = false;

    if (s == -1) {
      return null;
    }

    String domain = login.substring((s + 1));

    try {
      SRVRecord srvRecords[] = NetworkUtils.getSRVRecords("xmpp-client", "tcp", domain);

      if (srvRecords != null) {
        // To detect that account is a google ones, we try following:
        // - lookup in SRV and see if it is google.com;
        // - if the account has been created with GoogleTalk form;
        // - if it is an "external" google contact.

        // SRV checks
        for (SRVRecord srv : srvRecords) {
          if (srv.getTarget().endsWith("google.com") || srv.getTarget().endsWith("google.com.")) {
            isGoogleAppsOrGmail = true;
            break;
          }
        }
      }

      // GoogleTalk based account or external Google Contacts ?
      if (!isGoogleAppsOrGmail) {
        isGoogleAppsOrGmail = googleTalk;
      }

      if (isGoogleAppsOrGmail) {
        if (cnx == null) {
          cnx = new GoogleContactsConnectionImpl(login, password);

          if (cnx.connect()
              == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) {
            synchronized (this) {
              if (settings != null) {
                cnx = null;
                return null;
              } else {
                settings = new AccountSettingsForm();
              }
            }
            settings.setModal(true);
            settings.loadData(cnx);
            int ret = settings.showDialog();

            if (ret == 1) {
              cnx = settings.getConnection();
              GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx);
            } else {
              cnx = null;
            }
          }
        } else if (cnx.connect()
            == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) {
          synchronized (this) {
            if (settings != null) {
              cnx = null;
              return null;
            } else {
              settings = new AccountSettingsForm();
            }
          }
          settings.setModal(true);
          settings.loadData(cnx);
          int ret = settings.showDialog();

          if (ret == 1) {
            cnx = settings.getConnection();
            GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx);
          } else {
            cnx = null;
          }
        }
      } else {
        cnx = null;
      }
    } catch (Exception e) {
      logger.info("GoogleContacts connection error", e);
      return null;
    }

    return (GoogleContactsConnectionImpl) cnx;
  }
Пример #4
0
  /**
   * Attach JAIN-SIP <tt>SipProvider</tt> and <tt>ListeningPoint</tt> to the stack either for clear
   * communications or TLS. Clear UDP and TCP <tt>ListeningPoint</tt>s are not handled separately as
   * the former is a fallback for the latter (depending on the size of the data transmitted). Both
   * <tt>ListeningPoint</tt>s must be bound to the same address and port in order for the related
   * <tt>SipProvider</tt> to be created. If a UDP or TCP <tt>ListeningPoint</tt> cannot bind, retry
   * for both on another port.
   *
   * @param preferredPort which port to try first to bind.
   * @param retries how many times should we try to find a free port to bind
   * @param secure whether to create the TLS SipProvider. or the clear UDP/TCP one.
   * @throws TransportNotSupportedException in case we try to create a provider for a transport not
   *     currently supported by jain-sip
   * @throws InvalidArgumentException if we try binding to an illegal port (which we won't)
   * @throws ObjectInUseException if another <tt>SipProvider</tt> is already associated with this
   *     <tt>ListeningPoint</tt>.
   * @throws TransportAlreadySupportedException if there is already a ListeningPoint associated to
   *     this <tt>SipProvider</tt> with the same transport of the <tt>ListeningPoint</tt>.
   * @throws TooManyListenersException if we try to add a new <tt>SipListener</tt> with a
   *     <tt>SipProvider</tt> when one was already registered.
   */
  private void createProvider(int preferredPort, int retries, boolean secure)
      throws TransportNotSupportedException, InvalidArgumentException, ObjectInUseException,
          TransportAlreadySupportedException, TooManyListenersException {
    String context = (secure ? "TLS: " : "clear UDP/TCP: ");

    if (retries < 0) {
      // very unlikely to happen with the default 50 retries
      logger.error(context + "couldn't find free ports to listen on.");
      return;
    }

    ListeningPoint tlsLP = null;
    ListeningPoint udpLP = null;
    ListeningPoint tcpLP = null;

    try {
      if (secure) {
        tlsLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.TLS);
        if (logger.isTraceEnabled()) logger.trace("TLS secure ListeningPoint has been created.");

        this.secureJainSipProvider = this.stack.createSipProvider(tlsLP);
        this.secureJainSipProvider.addSipListener(this);
      } else {
        udpLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.UDP);
        tcpLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.TCP);
        if (logger.isTraceEnabled())
          logger.trace("UDP and TCP clear ListeningPoints have " + "been created.");

        this.clearJainSipProvider = this.stack.createSipProvider(udpLP);
        this.clearJainSipProvider.addListeningPoint(tcpLP);
        this.clearJainSipProvider.addSipListener(this);
      }

      if (logger.isTraceEnabled()) logger.trace(context + "SipProvider has been created.");
    } catch (InvalidArgumentException ex) {
      // makes sure we didn't leave an open listener
      // as both UDP and TCP listener have to bind to the same port
      if (tlsLP != null) this.stack.deleteListeningPoint(tlsLP);
      if (udpLP != null) this.stack.deleteListeningPoint(udpLP);
      if (tcpLP != null) this.stack.deleteListeningPoint(tcpLP);

      // FIXME: "Address already in use" is not working
      // as ex.getMessage() displays in the locale language in SC
      // (getMessage() is always supposed to be English though)
      // this should be a temporary workaround
      // if (ex.getMessage().indexOf("Address already in use") != -1)
      // another software is probably using the port
      if (ex.getCause() instanceof java.io.IOException) {
        if (logger.isDebugEnabled())
          logger.debug("Port " + preferredPort + " seems in use for either TCP or UDP.");

        // tries again on a new random port
        int currentlyTriedPort = NetworkUtils.getRandomPortNumber();
        if (logger.isDebugEnabled()) logger.debug("Retrying bind on port " + currentlyTriedPort);
        this.createProvider(currentlyTriedPort, retries - 1, secure);
      } else throw ex;
    }
  }