/**
  * Exception processor for exceptions detected from the parser. (This is invoked by the parser
  * when an error is detected).
  *
  * @param sipMessage -- the message that incurred the error.
  * @param ex -- parse exception detected by the parser.
  * @param header -- header that caused the error.
  * @throws ParseException Thrown if we want to reject the message.
  */
 public void handleException(
     ParseException ex, SIPMessage sipMessage, Class hdrClass, String header, String message)
     throws ParseException {
   if (LogWriter.needsLogging) stack.logWriter.logException(ex);
   // Log the bad message for later reference.
   if ((hdrClass != null)
       && (hdrClass.equals(From.class)
           || hdrClass.equals(To.class)
           || hdrClass.equals(CSeq.class)
           || hdrClass.equals(Via.class)
           || hdrClass.equals(CallID.class)
           || hdrClass.equals(RequestLine.class)
           || hdrClass.equals(StatusLine.class))) {
     stack.logBadMessage(message);
     throw ex;
   } else {
     sipMessage.addUnparsed(header);
   }
 }
 /**
  * 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();
 }
  /**
   * 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 {
    }
  }