Beispiel #1
0
  /**
   *
   *
   * <pre>
   *  Alice        Proxy       Bob        Bob(2)       HSS
   * 1  | INVITE     |          |           |           |
   *    |----------->|          |           |           |
   * 2  |            | INVITE   |           |           |
   *    |            |--------->|           |           |
   * 3  |            |      404 |           |           |
   *    |            |<---------|           |           |
   * 4  |            | ACK      |           |           |
   *    |            |--------->|           |           |
   * 5  |            | UDR      |           |           |
   *    |            |--------------------------------->|
   * 6  |            |          |           |       UDA |
   *    |            |<---------------------------------|
   * 7  |            | INVITE   |           |           |
   *    |            |--------------------->|           |
   * 8  |            |          |       200 |           |
   *    |            |<---------------------|           |
   * 9  |        200 |          |           |           |
   *    |<-----------|          |           |           |
   * 10 | ACK        |          |           |           |
   *    |----------->|          |           |           |
   * 11 |            | ACK      |           |           |
   *    |            |--------------------->|           |
   * 12 | BYE        |          |           |           |
   *    |----------->|          |           |           |
   * 13 |            | BYE      |           |           |
   *    |            |--------------------->|           |
   * 14 |            |          |       200 |           |
   *    |            |<---------------------|           |
   * 15 |        200 |          |           |           |
   *    |<-----------|          |           |           |
   * </pre>
   */
  @Test
  public void testProxyDiameter() throws Throwable {
    Endpoint bob = createEndpoint("bob");
    UaRunnable callB = new UasScript.NotFound(bob.getUserAgent());
    Endpoint bob2 = createEndpoint("bob");
    UaRunnable callC = new UasScript.OkBye(bob2.getUserAgent());

    callB.start();
    callC.start();

    SipServletRequest request = _ua.createRequest(SipMethods.INVITE, bob.getUri());
    request.setRequestURI(bob.getContact().getURI());
    request.addHeader("proxy", bob2.getContact().toString());
    Call callA = _ua.createCall(request);

    try {
      assertThat(callA.waitForResponse(), isSuccess());
      callA.createAck().send();
      Thread.sleep(200);
      callA.createBye().send();
      assertThat(callA.waitForResponse(), isSuccess());
      callB.assertDone();
      callC.assertDone();
    } finally {
      checkForFailure();
    }
  }
 @Override
 public synchronized void forwardTo(final Endpoint endpoint, final Map<String, String> headers)
     throws SignalException, IllegalStateException {
   URI target = null;
   try {
     target = _ctx.getSipFactory().createURI(endpoint.getURI().toString());
   } catch (final ServletParseException e) {
     throw new IllegalArgumentException(e);
   }
   this.checkState();
   _forwarded = true;
   final SipServletRequest req =
       _ctx.getSipFactory()
           .createRequest(
               _req.getApplicationSession(), _req.getMethod(), _req.getFrom(), _req.getTo());
   req.setRequestURI(target);
   SIPHelper.addHeaders(req, headers);
   SIPHelper.copyContent(_req, req);
   SIPHelper.linkSIPMessage(_req, req);
   try {
     req.send();
   } catch (final IOException e) {
     throw new SignalException(e);
   }
 }
Beispiel #3
0
  /**
   *
   *
   * <pre>
   *  Alice        Proxy         Bob
   * 1  | INVITE     |            |
   *    |----------->|            |
   * 2  |            | INVITE     |
   *    |            |----------->|
   * 3  |            |        180 |
   *    |            |<-----------|
   * 4  |        180 |            |
   *    |<-----------|            |
   * 5  |            | CANCEL     |
   *    |            |----------->|
   * 6  |        408 |            |
   *    |<-----------|            |
   * 7  |            | 200/CANCEL |
   *    |            |<-----------|
   * 8  |            | 487/INVITE |
   *    |            |<-----------|
   * 9  |            | ACK        |
   *    |            |----------->|
   * 10 | ACK        |            |
   *    |----------->|            |
   * </pre>
   */
  @Test
  public void testVirtualBranch() throws Exception {
    Endpoint bob = createEndpoint("bob");
    UaRunnable callB = new UasScript.RingingCanceled(bob.getUserAgent());

    callB.start();

    SipServletRequest request = _ua.createRequest(SipMethods.INVITE, bob.getUri());
    request.setRequestURI(bob.getContact().getURI());
    Call callA = _ua.createCall(request);

    assertThat(callA.waitForResponse(), hasStatus(SipServletResponse.SC_REQUEST_TIMEOUT));
    checkForFailure();
  }
Beispiel #4
0
  /**
   * Ensure that the servlet is not invoked if session is invalidated.
   *
   * <p>See http://jira.cipango.org/browse/CIPANGO-121
   *
   * <pre>
   *  Alice        Proxy       Bob
   * 1  | INVITE     |          |
   *    |----------->|          |
   * 2  |            | INVITE   |
   *    |            |--------->|
   * 3  |            |      200 |
   *    |            |<---------|
   * 4  |        200 |          |
   *    |<-----------|          |
   * 5  | ACK        |          |
   *    |----------->|          |
   * 6  |            | ACK      |
   *    |            |--------->|
   * 7  | BYE        |          |
   *    |----------->|          |
   * 8  |            | BYE      |
   *    |            |--------->|
   * 9  |            |      200 |
   *    |            |<---------|
   * 10 |        200 |          |
   *    |<-----------|          |
   * </pre>
   */
  @Test
  public void testInvalidateBefore200() throws Exception {
    Endpoint bob = createEndpoint("bob");
    UaRunnable callB = new UasScript.OkBye(bob.getUserAgent());

    callB.start();

    SipServletRequest request = _ua.createRequest(SipMethods.INVITE, bob.getUri());
    request.setRequestURI(bob.getContact().getURI());
    Call callA = _ua.createCall(request);
    assertThat(callA.waitForResponse(), isSuccess());
    callA.createAck().send();
    callA.createBye().send();

    SipServletResponse response = callA.waitForResponse();
    assertThat(response, isSuccess());
    assertThat(response.getHeader("error"), is(nullValue()));
  }
Beispiel #5
0
  /**
   * Ensures that - DNS resolution is done using NAPTR and SRV in proxy mode; - retry is done if a
   * 503 is received.
   *
   * <p>To run this test, the DNS server for domain cipango.voip should be configured with
   *
   * <pre>
   * bob         IN NAPTR 90  40  "s"  "SIP+D2U"      ""  _sip._udp.bob
   * _sip._udp.bob           SRV 0 0 5064 local
   * _sip._udp.bob           SRV 5 0 5063 local
   * </pre>
   *
   * Note:This test is marked as ignored as it requires a specific DNS configuration.
   */
  @Ignore
  public void dnsCase() throws Exception {
    final Endpoint bob = createEndpoint("bob");
    bob.getUserAgent()
        .setDefaultHandler(
            new MessageHandler() {
              public void handleRequest(SipServletRequest request)
                  throws IOException, ServletException {
                SipServletResponse response =
                    bob.getUserAgent().createResponse(request, SipServletResponse.SC_ACCEPTED);
                response.addHeader("X-Dns", "ok");
                response.send();
              }

              public void handleResponse(SipServletResponse response)
                  throws IOException, ServletException {}
            });

    final Endpoint bob2 = createEndpoint("bob");
    bob2.getUserAgent()
        .setDefaultHandler(
            new MessageHandler() {
              public void handleRequest(SipServletRequest request)
                  throws IOException, ServletException {
                SipServletResponse response =
                    bob.getUserAgent()
                        .createResponse(request, SipServletResponse.SC_SERVICE_UNAVAILABLE);
                response.send();
              }

              public void handleResponse(SipServletResponse response)
                  throws IOException, ServletException {}
            });

    SipServletRequest request = _ua.createRequest(SipMethods.MESSAGE, bob.getUri());
    request.setRequestURI(_sipClient.getFactory().createURI("sip:bob.cipango.voip"));
    Call call = _ua.createCall(request);
    assertThat(call.waitForResponse(), hasStatus(SipServletResponse.SC_ACCEPTED));

    checkForFailure();
  }
Beispiel #6
0
  /**
   *
   *
   * <pre>
   *  Alice         Proxy             Proxy       Bob
   * 1  | INVITE      |                 |          |
   *    |------------>|                 |          |
   * 2  |             |INVITE tel:1234  |          |
   *    |             |---------------->|          |
   * 3  |             |                 | INVITE   |
   *    |             |                 |--------->|
   * 4  |             |                 |      603 |
   *    |             |                 |<---------|
   * 5  |             |             603 |          |
   *    |             |<----------------|          |
   * 6  |         603 |                 |          |
   *    |<------------|                 |          |
   * 7  | ACK         |                 |          |
   *    |------------>|                 |          |
   * 8  |             |ACK              |          |
   *    |             |---------------->|          |
   * 9  |             |                 | ACK      |
   *    |             |                 |--------->|
   * </pre>
   */
  @Test
  public void testTelUri() throws Exception {
    final Endpoint bob = createEndpoint("bob");
    bob.getUserAgent()
        .setDefaultHandler(
            new MessageHandler() {
              public void handleRequest(SipServletRequest request)
                  throws IOException, ServletException {
                assertThat(request.getHeader("req-uri"), containsString("tel:1234"));
                bob.getUserAgent().createResponse(request, SipServletResponse.SC_DECLINE).send();
              }

              public void handleResponse(SipServletResponse response)
                  throws IOException, ServletException {}
            });

    SipServletRequest request = _ua.createRequest(SipMethods.INVITE, bob.getUri());
    request.setRequestURI(bob.getContact().getURI());
    Call call = _ua.createCall(request);
    assertThat(call.waitForResponse(), hasStatus(SipServletResponse.SC_DECLINE));
  }
Beispiel #7
0
  /**
   * @param request
   * @param client
   * @param toClient
   * @throws IOException
   */
  public static boolean redirectToB2BUA(
      final SipServletRequest request,
      final Client client,
      Client toClient,
      DaoManager storage,
      SipFactory sipFactory)
      throws IOException {
    request.getSession().setAttribute("lastRequest", request);
    if (logger.isInfoEnabled()) {
      logger.info("B2BUA (p2p proxy): Got request:\n" + request.getMethod());
      logger.info(
          String.format(
              "B2BUA: Proxying a session between %s and %s", client.getUri(), toClient.getUri()));
    }

    if (daoManager == null) {
      daoManager = storage;
    }

    String user = ((SipURI) request.getTo().getURI()).getUser();

    final RegistrationsDao registrations = daoManager.getRegistrationsDao();
    final Registration registration = registrations.getRegistration(user);
    if (registration != null) {
      final String location = registration.getLocation();
      SipURI to;
      SipURI from;
      try {
        to = (SipURI) sipFactory.createURI(location);
        from =
            (SipURI)
                sipFactory.createURI(
                    (registrations.getRegistration(client.getLogin())).getLocation());

        final SipSession incomingSession = request.getSession();
        // create and send the outgoing invite and do the session linking
        incomingSession.setAttribute(B2BUA_LAST_REQUEST, request);
        SipServletRequest outRequest =
            sipFactory.createRequest(
                request.getApplicationSession(),
                request.getMethod(),
                request.getFrom().getURI(),
                request.getTo().getURI());
        outRequest.setRequestURI(to);

        if (request.getContent() != null) {
          final byte[] sdp = request.getRawContent();
          String offer = null;
          if (request.getContentType().equalsIgnoreCase("application/sdp")) {
            // Issue 308: https://telestax.atlassian.net/browse/RESTCOMM-308
            String externalIp = request.getInitialRemoteAddr();
            // Issue 306: https://telestax.atlassian.net/browse/RESTCOMM-306
            final String initialIpBeforeLB = request.getHeader("X-Sip-Balancer-InitialRemoteAddr");
            try {
              if (initialIpBeforeLB != null && !initialIpBeforeLB.isEmpty()) {
                offer = patch(sdp, initialIpBeforeLB);
              } else {
                offer = patch(sdp, externalIp);
              }
            } catch (SdpException e) {
              logger.error("Unexpected exception while patching sdp ", e);
            }
          }
          if (offer != null) {
            outRequest.setContent(offer, request.getContentType());
          } else {
            outRequest.setContent(sdp, request.getContentType());
          }
        }

        final SipSession outgoingSession = outRequest.getSession();
        if (request.isInitial()) {
          incomingSession.setAttribute(B2BUA_LINKED_SESSION, outgoingSession);
          outgoingSession.setAttribute(B2BUA_LINKED_SESSION, incomingSession);
        }
        outgoingSession.setAttribute(B2BUA_LAST_REQUEST, outRequest);
        request.createResponse(100).send();
        // Issue #307: https://telestax.atlassian.net/browse/RESTCOMM-307
        request.getSession().setAttribute("toInetUri", to);
        outRequest.send();
        outRequest.getSession().setAttribute("fromInetUri", from);

        final CallDetailRecord.Builder builder = CallDetailRecord.builder();
        builder.setSid(Sid.generate(Sid.Type.CALL));
        builder.setDateCreated(DateTime.now());
        builder.setAccountSid(client.getAccountSid());
        builder.setTo(toClient.getFriendlyName());
        builder.setCallerName(client.getFriendlyName());
        builder.setFrom(client.getFriendlyName());
        // builder.setForwardedFrom(callInfo.forwardedFrom());
        // builder.setPhoneNumberSid(phoneId);
        builder.setStatus(CallStateChanged.State.QUEUED.name());
        builder.setDirection("Client-To-Client");
        builder.setApiVersion(client.getApiVersion());
        builder.setPrice(new BigDecimal("0.00"));
        // TODO implement currency property to be read from Configuration
        builder.setPriceUnit(Currency.getInstance("USD"));
        final StringBuilder buffer = new StringBuilder();
        buffer.append("/").append(client.getApiVersion()).append("/Accounts/");
        buffer.append(client.getAccountSid().toString()).append("/Calls/");
        buffer.append(client.getSid().toString());
        final URI uri = URI.create(buffer.toString());
        builder.setUri(uri);

        CallDetailRecordsDao records = daoManager.getCallDetailRecordsDao();
        CallDetailRecord callRecord = builder.build();
        records.addCallDetailRecord(callRecord);

        incomingSession.setAttribute(CDR_SID, callRecord.getSid());
        outgoingSession.setAttribute(CDR_SID, callRecord.getSid());

        return true; // successfully proxied the SIP request between two registered clients
      } catch (ServletParseException badUriEx) {
        if (logger.isInfoEnabled()) {
          logger.info(
              String.format("B2BUA: Error parsing Client Contact URI: %s", location), badUriEx);
        }
      }
    }
    return false;
  }