/**
   * Constructor - takes a datagram packet and a stack structure Extracts the address of the other
   * from the datagram packet and stashes away the pointer to the passed stack structure.
   *
   * @param packet is the UDP Packet that contains the request.
   * @param sipStack stack is the shared SipStack structure
   * @param notifier Channel notifier (not very useful for UDP).
   */
  public UDPMessageChannel(
      Datagram packet, SIPMessageStack sipStack, MessageProcessor messageProcessor) {
    incomingPacket = packet;
    stack = sipStack;
    this.messageProcessor = messageProcessor;

    myAddress = sipStack.getHostAddress();
    myPort = messageProcessor.getPort();

    Thread mythread = new Thread(this, "UDPMessageChannelThread");
    mythread.start();
  }
Ejemplo n.º 2
0
  /**
   * Constructor - gets called from the SIPMessageStack class with a socket on accepting a new
   * client. All the processing of the message is done here with the stack being freed up to handle
   * new connections. The sock input is the socket that is returned from the accept. Global data
   * that is shared by all threads is accessible in the Server structure.
   *
   * @param sock Socket from which to read and write messages. The socket is already connected (was
   *     created as a result of an accept).
   * @param sipStack the SIP Stack
   * @param channelNotifier Notifier (optional) that gets called when the channel is opened or
   *     closed.
   */
  protected TCPMessageChannel(
      SocketConnection sock, SIPMessageStack sipStack, TCPMessageProcessor msgProcessor)
      throws IOException {

    stack = sipStack;
    mySock = sock;
    myAddress = sipStack.getHostAddress();
    peerAddress = sock.getAddress();
    myClientInputStream = sock.openInputStream();
    myClientOutputStream = sock.openOutputStream();
    if (LogWriter.needsLogging) {
      LogWriter.logMessage("Creating new TCPMessageChannel " + this);
      LogWriter.logMessage(
          LogWriter.TRACE_DEBUG,
          "Channel parameters: "
              + "stack: "
              + stack
              + "\n"
              + "processor: "
              + msgProcessor
              + "\n"
              + "localAddress: "
              + myAddress
              + "\n"
              + "peerAddress: "
              + peerAddress
              + "\n"
              + "IS "
              + myClientInputStream
              + " Socket "
              + mySock);
    }
    stack.ioHandler.putSocket(
        stack.ioHandler.makeKey(mySock.getAddress(), mySock.getPort()),
        mySock,
        myClientOutputStream,
        myClientInputStream);

    mythread = new Thread(this, "TCPMessageChannel - incoming connection");

    this.tcpMessageProcessor = msgProcessor;
    this.myPort = this.tcpMessageProcessor.getPort();
    // Bug report by Vishwashanti Raj Kadiayl
    super.messageProcessor = msgProcessor;
    mythread.start();
  }
  /**
   * Constructor. We create one of these when we send out a message.
   *
   * @param targetAddr internet address of the place where we want to send messages.
   * @param port target port (where we want to send the message).
   * @param stack our SIP Stack.
   */
  public UDPMessageChannel(
      String targetAddr, int port, SIPMessageStack sipStack, UDPMessageProcessor processor) {
    if (LogWriter.needsLogging)
      LogWriter.logMessage(
          LogWriter.TRACE_DEBUG,
          "DEBUG, UDPMessageChannel, UDPMessageChannel(),"
              + " Creating message channel on "
              + targetAddr
              + "/"
              + port);

    stack = sipStack;
    this.peerPort = port;
    this.peerAddress = targetAddr;
    this.messageProcessor = processor;
    this.myPort = processor.getPort();
    this.myAddress = sipStack.getHostAddress();
    this.peerProtocol = "UDP";
  }
 /**
  * Constructor - connects to the given inet address. Acknowledgement -- Lamine Brahimi (IBM
  * Zurich) sent in a bug fix for this method. A thread was being uncessarily created.
  *
  * @param inetAddr inet address to connect to.
  * @param sipStack is the sip stack from which we are created.
  * @throws IOException if we cannot connect.
  */
 protected TLSMessageChannel(
     InetAddress inetAddr,
     int port,
     SIPMessageStack sipStack,
     TLSMessageProcessor messageProcessor)
     throws IOException {
   if (LogWriter.needsLogging) {
     sipStack.logWriter.logMessage("creating new TLSMessageChannel ");
     sipStack.logWriter.logStackTrace();
   }
   this.peerAddress = inetAddr;
   this.peerPort = port;
   this.myPort = messageProcessor.getPort();
   this.peerProtocol = "TLS";
   this.stack = sipStack;
   this.tlsMessageProcessor = messageProcessor;
   this.myAddress = sipStack.getHostAddress();
   // Bug report by Vishwashanti Raj Kadiayl
   this.key = MessageChannel.getKey(peerAddress, peerPort, "TLS");
   super.messageProcessor = messageProcessor;
 }
 /**
  * Constructor - gets called from the SIPStack class with a socket on accepting a new client. All
  * the processing of the message is done here with the stack being freed up to handle new
  * connections. The sock input is the socket that is returned from the accept. Global data that is
  * shared by all threads is accessible in the Server structure.
  *
  * @param sock Socket from which to read and write messages. The socket is already connected (was
  *     created as a result of an accept).
  * @param sipStack Ptr to SIP Stack
  */
 protected TLSMessageChannel(
     SSLSocket sock, SIPMessageStack sipStack, TLSMessageProcessor msgProcessor)
     throws IOException {
   if (LogWriter.needsLogging) {
     sipStack.logWriter.logMessage("creating new TLSMessageChannel ");
     sipStack.logWriter.logStackTrace();
   }
   mySock = sock;
   peerAddress = mySock.getInetAddress();
   myAddress = sipStack.getHostAddress();
   myClientInputStream = mySock.getInputStream();
   myClientOutputStream = mySock.getOutputStream();
   mythread = new Thread(this);
   mythread.setDaemon(true);
   mythread.setName("TLSMessageChannelThread");
   // Stash away a pointer to our stack structure.
   stack = sipStack;
   this.tlsMessageProcessor = msgProcessor;
   this.myPort = this.tlsMessageProcessor.getPort();
   // Bug report by Vishwashanti Raj Kadiayl
   super.messageProcessor = msgProcessor;
   // Can drop this after response is sent potentially.
   mythread.start();
 }
Ejemplo n.º 6
0
  /**
   * Constructor - connects to the given inet address. Acknowledgement -- Lamine Brahimi (IBM
   * Zurich) sent in a bug fix for this method. A thread was being unnecessarily created.
   *
   * @param inetAddr inet address to connect to.
   * @param sipStack is the sip stack from which we are created.
   * @param messageProcessor to whom a parsed message is passed
   * @throws IOException if we cannot connect.
   */
  protected TCPMessageChannel(
      String inetAddr, int port, SIPMessageStack sipStack, TCPMessageProcessor messageProcessor)
      throws IOException {

    this.peerAddress = inetAddr;
    this.peerPort = port;
    this.myPort = messageProcessor.getPort();
    this.peerProtocol = "TCP";
    this.stack = sipStack;
    this.tcpMessageProcessor = messageProcessor;
    this.myAddress = sipStack.getHostAddress();
    // Bug report by Vishwashanti Raj Kadiayl
    super.messageProcessor = messageProcessor;
    this.key = "TCP" + ":" + stack.ioHandler.makeKey(peerAddress, peerPort);

    if (LogWriter.needsLogging)
      LogWriter.logMessage(
          "Created new TCP Message Channel "
              + this
              + " with key "
              + key
              + "\nprocessor: "
              + messageProcessor);
  }
  /**
   * Gets invoked by the parser as a callback on successful message parsing (i.e. no parser errors).
   *
   * @param sipMessage Mesage to process (this calls the application for processing the message).
   */
  public void processMessage(SIPMessage sipMessage) throws Exception {
    try {
      if (sipMessage.getFrom() == null
          || // sipMessage.getFrom().getTag() == null ||
          sipMessage.getTo() == null
          || sipMessage.getCallId() == null
          || sipMessage.getCSeq() == null
          || sipMessage.getViaHeaders() == null) {
        String badmsg = sipMessage.encode();
        if (LogWriter.needsLogging) {
          stack.logWriter.logMessage("bad message " + badmsg);
          stack.logWriter.logMessage(">>> Dropped Bad Msg");
        }
        stack.logBadMessage(badmsg);
        return;
      }

      ViaList viaList = sipMessage.getViaHeaders();
      // For a request
      // first via header tells where the message is coming from.
      // For response, this has already been recorded in the outgoing
      // message.
      if (sipMessage instanceof SIPRequest) {
        Via v = (Via) viaList.first();
        if (v.hasPort()) {
          this.peerPort = v.getPort();
        } else this.peerPort = 5061;
        this.peerProtocol = v.getTransport();
        try {
          this.peerAddress = mySock.getInetAddress();
          // Check to see if the received parameter matches
          // the peer address and tag it appropriately.
          // Bug fix by [email protected]
          // Should record host address not host name
          // bug fix by  Joost Yervante Damand
          if (!v.getSentBy().getInetAddress().equals(this.peerAddress)) {
            v.setParameter(Via.RECEIVED, this.peerAddress.getHostAddress());
            // @@@ hagai
            v.setParameter(Via.RPORT, new Integer(this.peerPort).toString());
          }
        } catch (java.net.UnknownHostException ex) {
          // Could not resolve the sender address.
          if (LogWriter.needsLogging) {
            stack.logWriter.logMessage("Rejecting message -- could not resolve Via Address");
          }
          return;
        } catch (java.text.ParseException ex) {
          InternalErrorHandler.handleException(ex);
        }
        // Use this for outgoing messages as well.
        if (!this.isCached) {
          ((TLSMessageProcessor) this.messageProcessor).cacheMessageChannel(this);
          this.isCached = true;
          String key = IOHandler.makeKey(mySock.getInetAddress(), this.peerPort);
          stack.ioHandler.putSocket(key, mySock);
        }
      }

      // Foreach part of the request header, fetch it and process it

      long receptionTime = System.currentTimeMillis();
      //

      if (sipMessage instanceof SIPRequest) {
        // This is a request - process the request.
        SIPRequest sipRequest = (SIPRequest) sipMessage;
        // Create a new sever side request processor for this
        // message and let it handle the rest.

        if (LogWriter.needsLogging) {
          stack.logWriter.logMessage("----Processing Message---");
        }

        // Check for reasonable size - reject message
        // if it is too long.
        if (stack.getMaxMessageSize() > 0
            && sipRequest.getSize()
                    + (sipRequest.getContentLength() == null
                        ? 0
                        : sipRequest.getContentLength().getContentLength())
                > stack.getMaxMessageSize()) {
          SIPResponse sipResponse = sipRequest.createResponse(SIPResponse.MESSAGE_TOO_LARGE);
          byte[] resp = sipResponse.encodeAsBytes();
          this.sendMessage(resp, false);
          throw new Exception("Message size exceeded");
        }

        ServerRequestInterface sipServerRequest = stack.newSIPServerRequest(sipRequest, this);
        sipServerRequest.processRequest(sipRequest, this);
        if (this.stack.serverLog.needsLogging(ServerLog.TRACE_MESSAGES)) {
          if (sipServerRequest.getProcessingInfo() == null) {
            stack.serverLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                false,
                receptionTime);
          } else {
            this.stack.serverLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                sipServerRequest.getProcessingInfo(),
                false,
                receptionTime);
          }
        }
      } else {
        SIPResponse sipResponse = (SIPResponse) sipMessage;
        // This is a response message - process it.
        // Check the size of the response.
        // If it is too large dump it silently.
        if (stack.getMaxMessageSize() > 0
            && sipResponse.getSize()
                    + (sipResponse.getContentLength() == null
                        ? 0
                        : sipResponse.getContentLength().getContentLength())
                > stack.getMaxMessageSize()) {
          if (LogWriter.needsLogging) this.stack.logWriter.logMessage("Message size exceeded");
          return;
        }
        ServerResponseInterface sipServerResponse = stack.newSIPServerResponse(sipResponse, this);
        sipServerResponse.processResponse(sipResponse, this);
      }
    } finally {
    }
  }
Ejemplo n.º 8
0
  /**
   * Gets invoked by the parser as a callback on successful message parsing (i.e. no parser errors).
   *
   * @param sipMessage Mesage to process (this calls the application for processing the message).
   */
  public void processMessage(Message sipMessage) {

    if (!stack.isAlive()) {
      if (LogWriter.needsLogging)
        LogWriter.logMessage(
            LogWriter.TRACE_DEBUG,
            "MsgChannel " + this + " is dropping message as the stack is closing");
      return; // drop messages when closing, avoid Exceptions
    }

    try {
      if (LogWriter.needsLogging)
        LogWriter.logMessage(
            "[TCPMessageChannel]-> Processing incoming message: " + sipMessage.getFirstLine());
      if (sipMessage.getFromHeader() == null
          || sipMessage.getTo() == null
          || sipMessage.getCallId() == null
          || sipMessage.getCSeqHeader() == null
          || sipMessage.getViaHeaders() == null) {
        String badmsg = sipMessage.encode();
        if (LogWriter.needsLogging) {
          ServerLog.logMessage("bad message " + badmsg);
          ServerLog.logMessage(">>> Dropped Bad Msg");
        }
        stack.logBadMessage(badmsg);
        return;
      }

      ViaList viaList = sipMessage.getViaHeaders();
      // For a request
      // first via header tells where the message is coming from.
      // For response, this has already been recorded in the outgoing
      // message.
      if (sipMessage instanceof Request) {
        ViaHeader v = (ViaHeader) viaList.first();
        if (v.hasPort()) {
          viaPort = v.getPort();
        } else {
          viaPort = SIPMessageStack.DEFAULT_PORT;
        }
        this.peerProtocol = v.getTransport();
        try {
          if (peerPort == -1) peerPort = mySock.getPort();
          this.peerAddress = mySock.getAddress();

          // Log this because it happens when the remote host identifies
          // as a FQDN but this is not resolvable to an IP by the OS.
          // S40 doesn't have DNS settings, for instance, so if the APN
          // is not able to resolve all the addresses of the SIP/IMS core,
          // this problem will appear.
          if (peerAddress == null && LogWriter.needsLogging)
            LogWriter.logMessage(
                LogWriter.TRACE_EXCEPTION, "WARNING! Socket.getAddress() returned 'null'!!!");

          // Be warned, the host comparison may fail if socket.getAddress()
          // returns a domain name as the Via Host will be a numeric IP.
          // FIXME: No idea. Doing a DNS lookup or reverse DNS lookup
          // can be misleading because they can be non-matching, that is,
          // DNS(peerAddressName) != ReverseDNS(peerAddressIP)
          if (v.hasParameter(ViaHeader.RPORT) || !v.getHost().equals(this.peerAddress)) {
            if (LogWriter.needsLogging)
              LogWriter.logMessage(
                  LogWriter.TRACE_MESSAGES,
                  "WARNING! \"Received\" parameter "
                      + "has been temporarily disabled. Response will be sent to topmost Via Host: "
                      + v.getHost());
            this.peerAddress = v.getHost();
            //		                if (LogWriter.needsLogging)
            //			                   LogWriter.logMessage(LogWriter.TRACE_MESSAGES, "Adding
            // \"received\" parameter" +
            //			                   		" to incoming request with value: " + peerAddress +
            //			                   		" because it doesn't match the Via host " + v.getHost());
            //						v.setParameter(ViaHeader.RECEIVED, this.peerAddress);

          }

          if (v.hasParameter(ViaHeader.RPORT))
            v.setParameter(ViaHeader.RPORT, Integer.toString(this.peerPort));

          /*
           * If socket is invalid, close it because it is useless and dangerous.
           * Also if we ran out of slots for new sockets, as this could prevent
           * incoming connections from being accepted.
           */
          if (mySock.getAddress() == null
              || (stack.maxConnections != -1
                  && tcpMessageProcessor.getNumConnections() >= stack.maxConnections)) {
            stack.ioHandler.disposeSocket(mySock, myClientInputStream, myClientOutputStream);
            mySock = null;
            myClientInputStream = null;
            myClientOutputStream = null;
            if (stack.maxConnections != -1) {
              synchronized (tcpMessageProcessor) {
                tcpMessageProcessor.decreaseNumConnections();
                tcpMessageProcessor.notify();
              }
            }
          }
          // reuse socket even for outgoing requests
          else if (!this.isCached) {
            ((TCPMessageProcessor) this.messageProcessor).cacheMessageChannel(this);
            String key = "TCP" + ":" + stack.ioHandler.makeKey(peerAddress, peerPort);
            stack.ioHandler.putSocket(key, mySock, myClientOutputStream, myClientInputStream);
          }

        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      // System.out.println("receiver address = " + receiverAddress);

      // For each part of the request header, fetch it and process it
      long receptionTime = System.currentTimeMillis();

      if (sipMessage instanceof Request) {
        // This is a request - process the request.
        Request sipRequest = (Request) sipMessage;
        // Create a new sever side request processor for this
        // message and let it handle the rest.

        if (LogWriter.needsLogging) {
          LogWriter.logMessage("----Processing Message---");
        }

        // TODO: check maximum size of request

        SIPServerRequestInterface sipServerRequest = stack.newSIPServerRequest(sipRequest, this);

        if (sipServerRequest != null) {
          try {
            sipServerRequest.processRequest(sipRequest, this);

            ServerLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                false,
                receptionTime);
          } catch (SIPServerException ex) {
            ServerLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                ex.getMessage(),
                false,
                receptionTime);
            handleException(ex);
          }

        } else {
          if (LogWriter.needsLogging)
            LogWriter.logMessage("Dropping request -- null sipServerRequest");
        }

      } else {
        // This is a response message - process it.
        Response sipResponse = (Response) sipMessage;

        // TODO: check maximum size of the response

        SIPServerResponseInterface sipServerResponse =
            stack.newSIPServerResponse(sipResponse, this);

        if (LogWriter.needsLogging)
          LogWriter.logMessage("got a response interface " + sipServerResponse);

        try {
          // Responses with no ClienTransaction associated will not be processed
          // as they may cause a NPE in the EventScanner thread.
          if (sipServerResponse != null) sipServerResponse.processResponse(sipResponse, this);
          else {
            if (LogWriter.needsLogging) {
              LogWriter.logMessage("null sipServerResponse!");
            }
          }
        } catch (SIPServerException ex) {
          // An error occured processing the message -- just log it.
          ServerLog.logMessage(
              sipMessage,
              getPeerAddress().toString() + ":" + getPeerPort(),
              stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
              ex.getMessage(),
              false,
              receptionTime);
          // Ignore errors while processing responses??
        }
      }
    } catch (Exception ee) {
      if (stack.isAlive()) {
        throw new RuntimeException(ee.getClass() + ":" + ee.getMessage());
      }
      // else ignore exceptions
    } finally {
      //            this.tcpMessageProcessor.useCount --;
    }
  }
  /**
   * Actually process the parsed SIP message.
   *
   * @param sipMessage
   */
  public void processMessage(Message sipMessage) {

    if (sipMessage instanceof Request) {
      Request sipRequest = (Request) sipMessage;

      // This is a request - process it.
      SIPServerRequestInterface sipServerRequest = stack.newSIPServerRequest(sipRequest, this);
      // Drop it if there is no request returned
      if (sipServerRequest == null) {
        if (LogWriter.needsLogging) {
          LogWriter.logMessage("Null request interface returned");
        }
        return;
      }
      try {
        if (LogWriter.needsLogging)
          LogWriter.logMessage(
              "About to process " + sipRequest.getFirstLine() + "/" + sipServerRequest);
        sipServerRequest.processRequest(sipRequest, this);
        if (LogWriter.needsLogging)
          LogWriter.logMessage(
              "Done processing " + sipRequest.getFirstLine() + "/" + sipServerRequest);

        // So far so good -- we will commit this message if
        // all processing is OK.
        if (ServerLog.needsLogging(ServerLog.TRACE_MESSAGES)) {
          if (sipServerRequest.getProcessingInfo() == null) {
            ServerLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                false,
                new Long(receptionTime).toString());
          } else {
            ServerLog.logMessage(
                sipMessage,
                sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
                stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
                sipServerRequest.getProcessingInfo(),
                false,
                new Long(receptionTime).toString());
          }
        }
      } catch (SIPServerException ex) {

        if (ServerLog.needsLogging(ServerLog.TRACE_MESSAGES)) {
          ServerLog.logMessage(
              sipMessage,
              sipRequest.getViaHost() + ":" + sipRequest.getViaPort(),
              stack.getHostAddress() + ":" + stack.getPort(this.getTransport()),
              ex.getMessage(),
              false,
              new Long(receptionTime).toString());
        }
        handleException(ex);
      }

    } else {

      // Handle a SIP Response message.
      Response sipResponse = (Response) sipMessage;
      SIPServerResponseInterface sipServerResponse = stack.newSIPServerResponse(sipResponse, this);
      try {
        if (sipServerResponse != null) {
          sipServerResponse.processResponse(sipResponse, this);
          // Normal processing of message.
        } else {
          if (LogWriter.needsLogging) {
            LogWriter.logMessage("null sipServerResponse!");
          }
        }

      } catch (SIPServerException ex) {
        if (ServerLog.needsLogging(ServerLog.TRACE_MESSAGES)) {
          this.logResponse(sipResponse, receptionTime, ex.getMessage() + "-- Dropped!");
        }

        ServerLog.logException(ex);
      }
    }
  }