Exemplo n.º 1
0
String IdeSkin::findResource(String resource, bool httpPath) const
{	
	if(isValid() == false)
		return String::EMPTY;

	String res = resource;

	// Scatta l'evento. Se risponde, tengo quello.

	{
		String path = utils::makeFilePath(IdeSystem::instance()->getHtdocsPath(), resource);
		if(FileSystem::instance()->exists(path))
		{
			if(httpPath)
				return _S("/") + utils::makeFilePath(OS_HTDOCS_PATH, resource);		
			else
				return path;
		}
		else
		{
			/*
			// Se è richiesto un path HTTP, e la risorsa richiesta inizia per /,
			// allora la considero assoluta.
			// Ad esempio, nell'elenco CSS di una skin in una extension.
			// E' logico, dato che non ha senso che il nome di una risorsa inizi per /.
			if( (httpPath) && (resource.starts_with(_S("/"))) )
				return resource;
			*/

			OS_LOG_WARNING(String::format(_S("Resource '%S' not found.").c_str(), resource.c_str()));
			return String::EMPTY;
		}
	}	
}
Exemplo n.º 2
0
// Core send message logic.
OsStatus OsMsgQShared::doSendCore(OsMsg* pMsg,
                                  const OsTime& rTimeout,
                                  UtlBoolean isUrgent,
                                  UtlBoolean deleteWhenDone)
{
   if (mSendHookFunc != NULL)
   {
      if (mSendHookFunc(*pMsg))
      {
         // by returning TRUE, the mSendHookFunc indicates that it has handled
         // the message and there is no need to queue the message.
         if (deleteWhenDone)
         {
            // Delete *pMsg, since we are done with it.
            delete pMsg;
         }
         return OS_SUCCESS;
      }
   }

   enqueue(pMsg);

   int count = numMsgs();
   
   if (_reportFull && 2 * count > mMaxMsgs)
   {
     OS_LOG_WARNING(FAC_KERNEL,
                   "OsMsgQShared::doSendCore message queue '" << mName.data()
                   << "' is over half full - count = " << count
                   << " max = " << mMaxMsgs);
   }

   system_tap_queue_enqueue(mName.data(), 0, _queue.size());
   return OS_SUCCESS;
}
Exemplo n.º 3
0
  void onHouseKeepingTimer(const boost::system::error_code& e)
  {
    static int iteration = 0;
    //
    // This will fire every hour.  We will simply restart the timer
    // so io_serice thread does not exit.  If the operation is aborted
    // it would mean the io service has been terminated.
    //
    if (e != boost::asio::error::operation_aborted)
    {
      {
        mutex_lock lock(_queueMutex);
        OsTimer::Time now = OsTimer::now();
        OsTimer::Interval skew = now - _lastTick - (TIMER_SERVICE_TICK * TIMER_TIME_UNIT);
        _lastTick = now;

        if (iteration++ >= 10)
        {
          if (skew < TIMER_TIME_UNIT)
          {
            OS_LOG_DEBUG(FAC_KERNEL, "OsTimer::TimerService timer resolution: " << skew << " microseconds.");
          }
          else
          {
            OS_LOG_WARNING(FAC_KERNEL, "OsTimer::TimerService timer resolution: " << skew << " microseconds.");
          }
          iteration = 0;
        }

        //
        // Destroy timers that are queued back to us.
        //
        while (_timerQueue.size() > 0)
          _timerQueue.pop();
      }

      _houseKeepingTimer.expires_from_now(boost::posix_time::seconds(TIMER_SERVICE_TICK));
      _houseKeepingTimer.async_wait(boost::bind(&TimerService::onHouseKeepingTimer, this, boost::asio::placeholders::error));
      
    }
  }
Exemplo n.º 4
0
// Thread execution code.
int SipClient::run(void* runArg)
{
   OsMsg*    pMsg = NULL;
   OsStatus  res;
   // Buffer to hold data read from the socket but not yet parsed
   // into incoming SIP messages.
   UtlString readBuffer;
   bool      waitingToReportErr  = FALSE;    // controls whether to read-select on socket
   bool      tcpOnErrWaitForSend = TRUE;
   int       repeatedEOFs = 0;

   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                 "SipClient[%s]::run start  "
                 "tcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d",
                 mName.data(), tcpOnErrWaitForSend, waitingToReportErr,
                 mbTcpOnErrWaitForSend, repeatedEOFs);

   // Wait structure:
   struct pollfd fds[2];
   // Incoming message on the message queue (to be sent on the socket).
   fds[0].fd = mPipeReadingFd;
   // Socket ready to write (to continue sending message).
   // Socket ready to read (message to be received).

   do
   {
      assert(repeatedEOFs < 20);
      // The file descriptor for the socket may changemsg->getSendAddress(&fromIpAddress, &fromPort);, as OsSocket's
      // can be re-opened.
      fds[1].fd = mClientSocket->getSocketDescriptor();

      // Initialize the revents members.
      // This may not be necessary (the man page is not clear), but
      // Valgrind flags 'fds[*].revents' as undefined if they aren't
      // initialized.
      fds[0].revents = 0;
      fds[1].revents = 0;

      fds[0].events = POLLIN;   // only read-select on pipe

      // For non-blocking connect failures, don't read-select on socket if
      // the initial read showed an error but we have to wait to report it.
      if (!waitingToReportErr)
      {
          // This is the normal path.
          // Read the socket only if the socket is not shared.
          // If it is shared, the ancestral SipClient will read it.
          // If multiple threads attempt to read the socket, poll() may
          // succeed but another may read the data, leaving us to block on
          // read.
          fds[1].events = mbSharedSocket ? 0 : POLLIN;

          // Set wait for writing the socket if there is queued messages to
          // send.
          if (mWriteQueued)
          {
             // Wait for output on the socket to not block.
             fds[1].events |= POLLOUT;
          }

      }
      else
      {
          // just waiting to report error, ignore the socket
          fds[1].fd =-1;
          fds[1].events = 0;
      }

      // If there is residual data in the read buffer,
      // pretend the socket is ready to read.
      if (!readBuffer.isNull())
      {
         fds[1].revents = POLLIN;
      }
      else
      {
         // Otherwise, call poll() to wait.
         int resPoll = poll(&fds[0], sizeof (fds) / sizeof (fds[0]),
                        POLL_TIMEOUT);
         assert(resPoll >= 0 || (resPoll == -1 && errno == EINTR));
         if (resPoll != 0)
         {
             Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                           "SipClient[%s]::run "
                           "resPoll= %d revents: fd[0]= %x fd[1]= %x",
                           mName.data(),
                           resPoll, fds[0].revents, fds[1].revents );
         }
      }

      if ((fds[1].revents & (POLLERR | POLLHUP)) != 0)
      {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipClient[%s]::run "
                        "SipMessage::poll error(%d) ",
                        mName.data(), errno);

          if (OsSocket::isFramed(mClientSocket->getIpProtocol()))
          {
              Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                            "SipClient[%s]::run "
                            "SipMessage::poll error(%d) got POLLERR | POLLHUP on UDP socket",
                            mName.data(), errno);

          }
          else	// eg. tcp socket
          // This client's socket is a connection-oriented protocol and the
          // connection has been terminated (probably by the remote end).
          // We must terminate the SipClient.
          // We drop the queued messages, but we do not report them to
          // SipUserAgent as failed sends.  This will cause SipUserAgent to
          // retry the send using the same transport (rather than continuing
          // to the next transport), which should cause a new connection to
          // be made to the remote end.
          {
              // On non-blocking connect failures, we need to get the first send message
              // in order to successfully trigger the protocol fallback mechanism
              if (!tcpOnErrWaitForSend)
              {
                 // Return all buffered messages with a transport error indication.
                 emptyBuffer(TRUE);
                 clientStopSelf();
              }
              else
              {
                 fds[1].revents &= ~(POLLERR | POLLHUP);  // clear error bit if waiting
                 waitingToReportErr = TRUE;
              }
          }
      }

      // Check for message queue messages (fds[0]) before checking the socket(fds[1]),
      // to make sure that we process shutdown messages promptly, even
      // if we would be spinning trying to service the socket.
      else if ((fds[0].revents & POLLIN) != 0)
      {
         // Poll finished because the pipe is ready to read.
         // (One byte in pipe means message available in queue.)
         // Only a SipClient with a derived SipClientWriteBuffer
         // uses the pipe in the Sip message send process

         // Check to see how many messages are in the queue.
         int numberMsgs = (getMessageQueue())->numMsgs();
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "SipClient[%s]::run got pipe-select  "
                       "Number of Messages waiting: %d",
                       mName.data(),
                       numberMsgs);
         int i;
         char buffer[1];
         for (i = 0; i < numberMsgs; i++)
         {
            // Receive the messages.
            res = receiveMessage((OsMsg*&) pMsg, OsTime::NO_WAIT);
            assert(res == OS_SUCCESS);

            // Normally, this is a SIP message for the write buffer.  Once we have gotten
            // here, we are able to report any initial non-blocking connect error.
            mbTcpOnErrWaitForSend = FALSE;
            tcpOnErrWaitForSend = FALSE;
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run got pipe-select  "
                          "mbTcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d",
                          mName.data(), mbTcpOnErrWaitForSend, waitingToReportErr,
                          mbTcpOnErrWaitForSend, repeatedEOFs);

            // Read 1 byte from the pipe to clear it for this message.  One byte is
            // inserted into the pipe for each message.
            assert(read(mPipeReadingFd, &buffer, 1) == 1);

            if (!handleMessage(*pMsg))            // process the message (from queue)
            {
               OsServerTask::handleMessage(*pMsg);
            }

            if (!pMsg->getSentFromISR())
            {
               pMsg->releaseMsg();                         // free the message
            }

            // In order to report an unframed(eg TCP) socket error to SipUserAgent dispatcher,
            // the error must be carried in a sip message from the client's message queue.
            // The message holds all the identifying information.
            if (waitingToReportErr)
            {
                // Return all buffered messages with a transport error indication.
                emptyBuffer(TRUE);
                clientStopSelf();
            }
         }
      } // end reading msg-available-for-output-queue pipe

      else if ((fds[1].revents & POLLOUT) != 0)
      {
         // Poll finished because socket is ready to write.

         // Call method to continue writing data.
         writeMore();
      }
      else if ((fds[1].revents & POLLIN) != 0)
      {
         // Poll finished because socket is ready to read.

         // Read message.
         // Must allocate a new message because SipUserAgent::dispatch will
         // take ownership of it.

         SipMessage* msg = new SipMessage;
         int res = msg->read(mClientSocket,
                             HTTP_DEFAULT_SOCKET_BUFFER_SIZE,
                             &readBuffer);

         if (res >= 65536)
         {
           //
           // This is more than the allowable size of a SIP message.  Discard!
           //
            UtlString remoteHostAddress;
            int remoteHostPort;
            msg->getSendAddress(&remoteHostAddress, &remoteHostPort);
            OS_LOG_WARNING(FAC_SIP, "Received a SIP Message ("
             << res << " bytes) beyond the maximum allowable size from host "
             << remoteHostAddress.data() << ":" << remoteHostPort);
            delete msg;
            readBuffer.remove(0);
            continue;
         }

         // Use readBuffer to hold any unparsed data after the message
         // we read.
         // Note that if a message was successfully parsed, readBuffer
         // still contains as its prefix the characters of that message.
         // We save them for logging purposes below and will delete them later.

         UtlString remoteHostAddress;
         int remoteHostPort;
         msg->getSendAddress(&remoteHostAddress, &remoteHostPort);
         if (!mClientSocket->isSameHost(remoteHostAddress.data(), mLocalHostAddress.data()))
         {
           try
           {
             if (!remoteHostAddress.isNull())
             {
               boost::asio::ip::address remoteIp = boost::asio::ip::address::from_string(remoteHostAddress.data());

               if (rateLimit().isBannedAddress(remoteIp))
               {
                  delete msg;
                  readBuffer.remove(0);
                  continue;
               }

               rateLimit().logPacket(remoteIp, 0);
             }
           }
           catch(const std::exception& e)
           {
             Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_CRIT, 
               "SipClient[%s]::run rate limit exception: %s",  mName.data(), e.what());
           }
         }


         // Note that input was processed at this time.
         touch();

         //
         // Count the CR/LF to see if this is a keep-alive
         //
         int crlfCount = 0;
         for (int i = 0; i < res; i++)
         {
           if (readBuffer(i) == '\r' || readBuffer(i) == '\n')
           {
             crlfCount++;
           } else
           {
             break;
           }
         }

         if (res == crlfCount)
         {
             repeatedEOFs = 0;
             // The 'message' was a keepalive (CR-LF or CR-LF-CR-LF).
             UtlString fromIpAddress;
             int fromPort;
             UtlString buffer;
             int bufferLen;

             // send one CRLF set in the reply
             buffer.append("\r\n");
             bufferLen = buffer.length();

             // Get the send address for response.
             msg->getSendAddress(&fromIpAddress, &fromPort);
             if ( !portIsValid(fromPort))
             {
                 fromPort = defaultPort();
             }

            // Log the message at DEBUG level.
            // Only bother processing if the logs are enabled
            if (   mpSipUserAgent->isMessageLoggingEnabled()
                   || Os::Logger::instance().willLog(FAC_SIP_INCOMING, PRI_DEBUG)
               )
            {
               UtlString logMessage;
               logMessage.append("Read keepalive message:\n");
               logMessage.append("----Local Host:");
               logMessage.append(mLocalHostAddress);
               logMessage.append("---- Port: ");
               logMessage.appendNumber(
                  portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort());
               logMessage.append("----\n");
               logMessage.append("----Remote Host:");
               logMessage.append(fromIpAddress);
               logMessage.append("---- Port: ");
               logMessage.appendNumber(
                  portIsValid(fromPort) ? fromPort : defaultPort());
               logMessage.append("----\n");

               logMessage.append(readBuffer.data(), res);
               UtlString messageString;
               logMessage.append(messageString);
               logMessage.append("====================END====================\n");

               // Don't bother to send the message to the SipUserAgent for its internal log.

               // Write the message to the syslog.
               Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_DEBUG, "%s", logMessage.data());
            }

            // send the CR-LF response message
            switch (mSocketType)
            {
            case OsSocket::TCP:
            {
               Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                             "SipClient[%s]::run send TCP keep-alive CR-LF response, ",
                             mName.data());
               SipClientSendMsg sendMsg(OsMsg::OS_EVENT,
                                        SipClientSendMsg::SIP_CLIENT_SEND_KEEP_ALIVE,
                                        fromIpAddress,
                                        fromPort);
                handleMessage(sendMsg);     // add newly created keep-alive to write buffer
            }
               break;
            case OsSocket::UDP:
            {
                Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                              "SipClient[%s]::run send UDP keep-alive CR-LF response, ",
                              mName.data());
               (dynamic_cast <OsDatagramSocket*> (mClientSocket))->write(buffer.data(),
                                                                         bufferLen,
                                                                         fromIpAddress,
                                                                         fromPort);
            }
               break;
            default:
               break;
            }

            // Delete the SipMessage allocated above, which is no longer needed.
            delete msg;

            // Now that logging is done, remove the parsed bytes and
            // remember any unparsed input for later use.
            readBuffer.remove(0, res);
         }  // end keep-alive msg

         else if (res > 0)      // got message, but not keep-alive
         {
            // Message successfully read.
            repeatedEOFs = 0;

            // Do preliminary processing of message to log it,
            // clean up its data, and extract any needed source address.
            preprocessMessage(*msg, readBuffer, res);

            // Dispatch the message.
            // dispatch() takes ownership of *msg.
            mpSipUserAgent->dispatch(msg);

            // Now that logging is done, remove the parsed bytes and
            // remember any unparsed input for later use.
            readBuffer.remove(0, res);
         }  // end process read of >0 bytes
         else
         {
            // Something went wrong while reading the message.
            // (Possibly EOF on a connection-oriented socket.)
            repeatedEOFs++;

            // Delete the SipMessage allocated above, which is no longer needed.
            delete msg;
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run SipMessage::read returns %d (error(%d) or EOF), "
                          "readBuffer = '%.1000s'",
                          mName.data(), res, errno, readBuffer.data());

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run error wait status  "
                          "tcpOnErrWaitForSend-%d waitingToReportErr-%d "
                          "mbTcpOnErrWaitForSend-%d repeatedEOFs-%d "
                          "protocol %d framed %d",
                          mName.data(),
                          tcpOnErrWaitForSend, waitingToReportErr,
                          mbTcpOnErrWaitForSend, repeatedEOFs,
                          mClientSocket->getIpProtocol(),
                          OsSocket::isFramed(mClientSocket->getIpProtocol()));

            // If the socket is not framed (is connection-oriented),
            // we need to abort the connection and post a message
            // :TODO: This doesn't work right for framed connection-oriented
            // protocols (like SCTP), but OsSocket doesn't have an EOF-query
            // method -- we need to close all connection-oriented
            // sockets as well in case it was an EOF.
            // Define a virtual function that returns the correct bit.
            if (!OsSocket::isFramed(mClientSocket->getIpProtocol()))
            {
                // On non-blocking connect failures, we need to get the first send message
                // in order to successfully trigger the protocol fallback mechanism
                if (!tcpOnErrWaitForSend)
                {
                   // Return all buffered messages with a transport error indication.
                   emptyBuffer(TRUE);
                   clientStopSelf();
                }
                else
                {
                   fds[1].revents &= ~(POLLERR | POLLHUP);  // clear error bit if waiting
                   waitingToReportErr = TRUE;
                }
            }
            // Delete the data read so far, which will not have been
            // deleted by HttpMessage::read.
            readBuffer.remove(0);
         }
      } // end POLLIN reading socket
   }
   while (isStarted());

   return 0;        // and then exit
}
Exemplo n.º 5
0
void StateQueuePublisher::internal_run()
{
  zmq::context_t context(1);
  zmq::socket_t socket(context, ZMQ_PUB);

  try
  {
    socket.bind(_zmqBindAddress.c_str());
  }
  catch(zmq::error_t& error_)
  {
    return;
  }

  OS_LOG_NOTICE(FAC_NET, "StateQueuePublisher::internal_run() "
          << "Started accepting subscriptions at " << _zmqBindAddress);
  
  while(!_terminate)
  {
    StateQueueRecord record;
    if (_queue.dequeue(record))
    {
      //
      // exit
      //
      if (_terminate)
        break;

      //
      // publish
      //
      std::string eventId = record.id;


      if (!record.watcherData && eventId.size() < 7)
      {
        OS_LOG_ERROR(FAC_NET, "StateQueuePublisher::publish eventId is too short - " << eventId);
        continue;
      }

      try
      {
        s_sendmore(socket, eventId);

        std::string data;

        if (!record.watcherData)
        {
          for (std::vector<std::string>::const_iterator iter = record.exclude.begin();
                  iter != record.exclude.end(); iter++)
          {
            data += *iter;
            data += " ";
          }

          if (data.empty())
            data = "initial_data";

          OS_LOG_DEBUG(FAC_NET, "StateQueuePublisher::publish "
                  << " message-id: " << eventId
                  << " exclude-app-id: " << data);
        }
        else
        {
          data = record.data;
        }

        //
        // Send the address
        //
        s_sendmore(socket, _zmqBindAddress);
        //
        // Send the data vector
        //
        s_sendmore(socket, data);
        //
        // Send the number of subscribers
        //
        std::string ev = eventId.substr(0, 7);
        int count = countSubscribers(ev);
        std::string strcount = boost::lexical_cast<std::string>(count);
        s_send(socket, strcount);


        OS_LOG_DEBUG(FAC_NET, "StateQueuePublisher::publish ZeroMQ send: " << eventId << ":" << data);

        if (!record.watcherData && !count)
        {
          OS_LOG_WARNING(FAC_NET, "StateQueuePublisher::publish "
                << "ZERO subscribers to handle message-id: " << eventId);
        }
      }
      catch(zmq::error_t& error_)
      {
        OS_LOG_WARNING(FAC_NET, "StateQueuePublisher::publish "
                << "ZMQ Error sending publish " << eventId << " Error: " << error_.what());
      }
    }
    else
    {
      OS_LOG_ERROR(FAC_NET, "FAILED TO DEQUEUE!");
    }
  }
  OS_LOG_NOTICE(FAC_NET, "StateQueuePublisher::internal_run() TERMINATED.");
}
Exemplo n.º 6
0
bool CallerAlias::getCallerAlias (
  const UtlString& identity,
  const UtlString& domain,
  UtlString& callerAlias_
) const
{
    if (!_pEntities)
        return false;

    EntityRecord userEntity;
    EntityRecord gatewayEntity;
    bool hasUserEntity = false;
    bool hasGatewayEntity = false;
    std::string callerAlias;
    OS_LOG_INFO(FAC_SIP, "CallerAlias::getCallerAlias - EntityDB::findByIdentity for identity=" << identity.str() << " domain=" << domain.str());

    hasUserEntity = _pEntities->collection().findByIdentity(identity.str(), userEntity);
    hasGatewayEntity = _pEntities->collection().findByIdentity(domain.str(), gatewayEntity);

    if (hasGatewayEntity && gatewayEntity.callerId().transformExtension)
    {
        size_t loc = identity.str().find("@");
        if (loc != std::string::npos)
        {
            std::string userId = identity.str().substr(0, loc);
            //
            // Check if we need to truncate the userId to a certain length
            //
            if (gatewayEntity.callerId().extensionLength > 0 && userId.length() > (size_t)gatewayEntity.callerId().extensionLength)
                userId = string_right(userId, gatewayEntity.callerId().extensionLength);

            //
            // Now check if a prefix is specified
            //
            if (!gatewayEntity.callerId().extensionPrefix.empty())
            {
                std::string buff = gatewayEntity.callerId().extensionPrefix;
                buff += userId;
                userId = userId = buff;
            }

            callerAlias = "<sip:";
            callerAlias += userId;
            callerAlias += identity.str().substr(loc);
            callerAlias += ">";
        }
    }
    else
    {
      if (hasUserEntity && !userEntity.callerId().id.empty())
          callerAlias = userEntity.callerId().id;
      else if (hasGatewayEntity)
          gatewayEntity.callerId().ignoreUserCalleId = true;

      if (hasGatewayEntity && gatewayEntity.callerId().ignoreUserCalleId)
      {
          if (gatewayEntity.callerId().enforcePrivacy)
          {
              callerAlias = "sip:[email protected]";
          }
          else if (!gatewayEntity.callerId().id.empty())
          {
              callerAlias = gatewayEntity.callerId().id;
          }
      }
    }
    
    if (!callerAlias.empty())
        callerAlias_ = callerAlias.c_str();
    else
        OS_LOG_WARNING(FAC_SIP, "CallerAlias::getCallerAlias - No caller alias configured for identity=" << identity.str() << " domain=" << domain.str());
    
    return !callerAlias.empty();
}