Пример #1
0
int ExtConn::onWrite()
{
    LS_DBG_L(this, "ExtConn::onWrite()");
    m_tmLastAccess = DateTime::s_curTime;
    int ret;
    switch (m_iState)
    {
    case CONNECTING:
        ret = onInitConnected();
        if (ret)
            break;
    //fall through
    case PROCESSING:
        ret = doWrite();
        break;
    case ABORT:
    case CLOSING:
    case DISCONNECTED:
        return 0;
    default:
        return 0;
    }
    if (ret == -1)
        ret = connError(errno);
    return ret;
}
Пример #2
0
int ExtConn::onRead()
{
    LS_DBG_L(this, "ExtConn::onRead()");
    m_tmLastAccess = DateTime::s_curTime;
    int ret;
    switch (m_iState)
    {
    case CONNECTING:
        ret = onInitConnected();
        break;
    case PROCESSING:
        ret = doRead();
        break;
    case ABORT:
    case CLOSING:
    case DISCONNECTED:
        return 0;
    default:
        // Not suppose to happen;
        return 0;
    }
    if (ret == -1)
        ret = connError(errno);
    return ret;
}
Пример #3
0
void ExtConn::onSecTimer()
{
    int secs = DateTime::s_curTime - m_tmLastAccess;
    if (m_iState == CONNECTING)
    {
        if (secs >= 2)
        {
            LS_NOTICE(this, "ExtConn timed out while connecting.");
            connError(ETIMEDOUT);
        }
    }
    else if (m_iState == DISCONNECTED)
    {
    }
    else if (getReq())
    {
        if (!m_iCPState && m_iReqProcessed == 0)
        {
            if (secs >= m_pWorker->getTimeout())
            {
                LS_NOTICE(this, "ExtConn timed out while processing.");
                connError(ETIMEDOUT);
            }
            else if ((secs == 10) && (getReq()->isRecoverable()))
            {
//                 LS_DBG_L(this, "No response in 10 seconds, possible dead "
//                          "lock, try starting a new instance.");
                m_pWorker->addNewProcess();
            }
        }
    }
    else if ((m_iState == PROCESSING)
             && (secs > m_pWorker->getConfigPointer()->getKeepAliveTimeout()))
    {
        LS_DBG_L(this, "Idle connection timed out, close!");
        close();
    }

}
Пример #4
0
void LsapiConn::onTimer()
{
    if ( m_respState && !m_reqReceived &&( DateTime::s_curTime - m_lReqSentTime >= 3 ))
    {
        LOG_NOTICE(( getLogger(), "[%s] No request delivery notification has been received from LSAPI application, possible dead lock.", getLogId() ));
        if ( ((LsapiWorker *)getWorker())->getConfig().getSelfManaged() )
            getWorker()->addNewProcess();
        else
            connError( ETIMEDOUT );
        return;
    }
/*    if ( m_lLastRespRecvTime )
    {
        long tm = time( NULL );
        long delta = tm - m_lLastRespRecvTime;
        if (( delta > getWorker()->getTimeout() )&&( m_iRespBodyRecv ))
        {
            if ( m_pChunkIS )
                LOG_INFO(( getLogger(), "[%s] Timeout, partial chunk encoded body received,"
                    " received: %d, chunk len: %d, remain: %d!",
                    getLogId(), m_iRespBodyRecv, m_pChunkIS->getChunkLen(),
                    m_pChunkIS->getChunkRemain() ));
            else
                LOG_INFO((getLogger(), "[%s] Timeout, partial response body received,"
                    " body len: %d, received: %d!",
                    getLogId(), m_iRespBodySize, m_iRespBodyRecv ));
            setState( CLOSING );
            if ( getConnector() )
                getConnector()->endResponse( 0, 0 );
            return;
        }
        else if (( m_pChunkIS )&&( delta > 2 ))
        {
            if ((!m_pChunkIS->getChunkLen())&&( getConnector() ))
            {
                LOG_INFO(( getLogger(), "[%s] Missing trailing CRLF in Chunked Encoding!",
                            getLogId() ));
                setState( CLOSING );
                getConnector()->endResponse( 0, 0 );
                return;
            }
        }
    }*/
        
    ExtConn::onTimer();
}
Пример #5
0
int ProxyConn::doError(int err)
{
    LS_DBG_L(this, "ProxyConn::doError()");
    if (getConnector())
    {
        int state = getConnector()->getState();
        if (!(state & (HEC_FWD_RESP_BODY | HEC_ABORT_REQUEST
                       | HEC_ERROR | HEC_COMPLETE)))
        {
            LS_DBG_L(this, "Proxy Peer closed connection, "
                     "try another connection!");
            connError(err);
            return 0;
        }
        if (!(state & HEC_COMPLETE))
            getConnector()->endResponse(SC_500, -1);
    }
    return 0;
}
Пример #6
0
int LsapiConn::doError( int err)
{
    if ( D_ENABLED( DL_LESS ) )
        LOG_D(( getLogger(), "[%s] LsapiConn::doError()", getLogId() ));
    if ( getConnector())
    {
        int state = getConnector()->getState();
        if ( !(state & (HEC_FWD_RESP_BODY | HEC_ABORT_REQUEST
                        | HEC_ERROR|HEC_COMPLETE) ))
        {
            if ( D_ENABLED( DL_LESS ) )
                LOG_D(( getLogger(), "[%s] Lsapi Peer closed connection, "
                            "try another connection!", getLogId() ));
            connError( err );
            return 0;
        }
        if ( !(state & HEC_COMPLETE) )
            getConnector()->endResponse( SC_500, -1 );
    }
    return 0;
}
Пример #7
0
int ExtConn::assignReq(ExtRequest *pReq)
{
    int ret;

    if (getState() > PROCESSING)
        close();
    assert(!m_iInProcess);
//    if ( m_iInProcess )
//    {
//        LS_WARN(this, "[ExtConn] connection is still in middle of a request,"
//                " close before assign a new request");
//        close();
//    }
    m_iCPState = 0;
    ret = addRequest(pReq);
    if (ret)
    {
        if (ret == -1)
            ret = SC_500;
        pReq->setHttpError(ret);
        return ret;
    }
    m_tmLastAccess = DateTime::s_curTime;
    if (getState() == PROCESSING)
    {
        ret = doWrite();
        onEventDone();
        //pConn->continueWrite();
    }
    else if (getState() != CONNECTING)
        ret = reconnect();
    if (ret == -1)
        return connError(errno);
    return 0;

}
Пример #8
0
/**
 * @ingroup shell
 *
 * Shell command (nc).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return 0 for success, 1 for error
 */
shellcmd xsh_nc(int nargs, char *args[])
{
    int a;
    ushort port;
    bool listen = FALSE;
    struct netaddr dst;
    struct netaddr src;
    tid_typ recvthr;
    tid_typ sendthr;
    int msg = 0;
    int dev;

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && 0 == strncmp(args[1], "--help", 7))
    {
        usage(args[0]);
        return 0;
    }

    port = 0;
    dst.type = NULL;
    src.type = NULL;

    /* Parse arguments */
    for (a = 1; a < nargs; a++)
    {
        if (args[a][0] != '-')
        {
            if (!listen && NULL == dst.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &dst);
            }
            else if (listen && NULL == src.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &src);
            }
            else if (NULL == port)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                port = atoi(args[a]);
            }
        }
        else
        {
            switch (args[a][1])
            {
                /* Listen on port */
            case 'l':
                listen = TRUE;
                break;
                /* Source IP */
            case 's':
                a++;
                if (a >= nargs || !isdigit(args[a][0]))
                {
                    return argError(args[a - 1]);
                }
                dot2ipv4(args[a], &src);
                break;
            default:
                return argError(args[a]);
            }
        }
    }

    /* Verify arguments */
    if (NULL == src.type)
    {
        fprintf(stderr, "Source/listen IP address required\n");
        return 1;
    }
    if (NULL == port)
    {
        fprintf(stderr, "Invalid port\n");
        return 1;
    }
    if (!listen && NULL == dst.type)
    {
        fprintf(stderr, "Remote IP address required\n");
        return 1;
    }

    /* Allocate a TCP device */
#ifdef NTCP
    dev = tcpAlloc();
#else
    dev = SYSERR;
#endif                          /* NTCP */
    if (SYSERR == dev)
    {
        return connError();
    }

    if (listen)
    {
        if (SYSERR == open(dev, &src, NULL, port, NULL, TCP_PASSIVE))
        {
            close(dev);
            return connError();
        }
    }
    else
    {
        if (SYSERR == open(dev, &src, &dst, NULL, port, TCP_ACTIVE))
        {
            close(dev);
            return connError();
        }
    }

    recvthr =
        create(ncRecv, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_recv", 1, dev);
    sendthr =
        create(ncSend, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_send", 1, dev);
    if ((SYSERR == recvthr) || (SYSERR == sendthr))
    {
        kill(recvthr);
        kill(sendthr);
        close(dev);
        fprintf(stderr, "Failed to spawn threads");
        return 1;
    }
    thrtab[recvthr].fdesc[0] = stdin;
    thrtab[recvthr].fdesc[1] = stdout;
    thrtab[recvthr].fdesc[2] = stderr;
    thrtab[sendthr].fdesc[0] = stdin;
    thrtab[sendthr].fdesc[1] = stdout;
    thrtab[sendthr].fdesc[2] = stderr;

    /* Start both threads */
    while (recvclr() != NOMSG);
    ready(recvthr, RESCHED_YES);
    ready(sendthr, RESCHED_NO);

    /* Wait for one thread to die */
    while ((msg != recvthr) && (msg != sendthr))
    {
        msg = receive();
    }
    sleep(10);

    /* Kill both threads */
    kill(recvthr);
    kill(sendthr);

    close(dev);
    return 0;
}
Пример #9
0
void Irc::parse(QString raw) {
  if (raw.startsWith(':'))
    raw = raw.right(raw.length() - 1);

#ifdef COLOR_WIPE
  QString xraw; int len = 0; int olen = raw.length();
  // dirty but useful color removal code
  do {
    do {
      if ( raw [len] == '\003' ) { // color, veo muuucho color
        len += 2;
        if ( raw [len].isNumber() ) len++;
        if ( raw [len] == ',' && raw [len+1].isDigit() ) { // color, veo aúuuun más color
          len += 2;
          if ( raw [len].isNumber() ) len++;
        }
      } else if ( raw [len] == '\002' || raw [len] == '\026' || raw [len] == '\035' ) // blablalba
        len++;
    } while ( raw [len] == '\003' || raw [len] == '\002'|| raw [len] == '\026'||
              raw [len] == '\035' ); // esto es una guarrada pero evita varios control codes consecutivos
      xraw.append(raw[len]);
      len++;
  } while( len < olen );
  raw = xraw;
#endif

  QStringList matrix = raw.split(' ');
  if( matrix[0] == "PING" ) { // Recibido ping, pongoneamos.
    sendData("PONG " + matrix[1]);
    emit PingPong();

  } else if ( matrix[0] == "ERROR" ) { // error de conexion, whichever
    emit connError(raw.right(raw.length() - 7)); //quita el "ERROR :" del principio y deja el msj limpio

  } else if ( matrix[1] == "PRIVMSG" || matrix[1] == "NOTICE" ) {
    QString nick = matrix[0].left(matrix[0].indexOf('!'));
    QString message = raw.right((raw.length() - 2) - raw.indexOf(" :"));
    QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" PRIVMSG") - nick.length()));

    if ( matrix[1] == "PRIVMSG" ) {
      if ( matrix[2].startsWith("#") ) { // mensaje de canal
        if ( message.startsWith("\001") ) // /ctcp
          if ( message.startsWith("\001ACTION ")) // me
            emit chanme ( nick, mask, matrix[2], message.right((message.length() - 8)) );
          else
            emit chanctcp ( nick, mask, matrix[2], message.right((message.length() - 1)) );
        else
          emit chanmsg ( nick, mask, matrix[2], message );
      } else { // mensaje en privado
        if ( message.startsWith("\001") ) // /me
          if ( message.startsWith("\001ACTION ")) // me
            emit queryme ( nick, mask, message.right((message.length() - 8)) );
          else
            emit queryctcp ( nick, mask, message.right((message.length() - 1)) );
        else
          emit querymsg ( nick, mask, message );
      }
    } else if ( matrix[1] == "NOTICE" ) {
      if ( matrix[2].startsWith("#") ) { // notice en canal
        emit channotice ( nick, mask, matrix[2], message );
      } else { // notice en privado
        emit querynotice ( nick, mask, message );
      }
    }
  } else if ( matrix[1] == "JOIN" ) { //join a un canal
    QString nick = matrix[0].left(matrix[0].indexOf('!'));
    QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" JOIN") - nick.length()));
    if( matrix[2].startsWith(':') )
        emit join(nick,mask,matrix[2].right( matrix[2].length() -1 ));
      else
        emit join(nick,mask,matrix[2]);

  } else if ( matrix[1] == "PART" || matrix[1] == "QUIT" ) { //handled together
    QString message = "", chan = "";
    if (raw.indexOf(" :") != -1)
      message = raw.right((raw.length() - 2) - raw.indexOf(" :"));
    QString nick = matrix[0].left(matrix[0].indexOf('!'));
    QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" PART") - nick.length()));

    if ( matrix[1] == "PART" ) {
      QString chan = raw.right((raw.length() - 1) - raw.indexOf(" #"));
      chan = chan.left(chan.indexOf(" :"));
      QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" PART") - nick.length()));
      emit part(nick,mask,chan,message);
    } else if ( matrix[1] == "QUIT" ) {
      QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" QUIT") - nick.length()));
      emit quit(nick,mask,message);
    }
  } else if ( matrix[1] == "NICK" ) {
    QString nick = matrix[0].left(matrix[0].indexOf('!'));
    QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" NICK") - nick.length()));
    QString newnick = raw.right((raw.length() - 2) - raw.indexOf(" :"));
    if (newnick == ownNick)
      emit ownNickChange(newnick);
    emit nickChange(nick,mask,newnick);
  } else if ( matrix[1] == "MODE" ) { // cambio de modo, pero no sé si es de usuario o canal.
    if ( matrix[2].startsWith('#') ) { // c mode
      QString nick = matrix[0].left(matrix[0].indexOf('!'));
      QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" MODE") - nick.length()));
      QString chan = matrix[2];
      QString mode = raw.right((raw.length() - raw.indexOf(" #")) - chan.length() - 2);
      emit modeChange(nick,mask,chan,mode);
    } else { // u mode
      if( matrix[3].startsWith(':') )
        emit umodeChange(matrix[0],matrix[2],matrix[3].right( matrix[3].length() -1 ));
      else
        emit umodeChange(matrix[0],matrix[2],matrix[3]);
    }
  } else if ( matrix[1] == "KICK" ) { // expulsión del canal
    if ( matrix[2].startsWith('#') ) { // c mode
      QString nick = matrix[0].left(matrix[0].indexOf('!'));
      QString mask = matrix[0].mid(matrix[0].indexOf('!') + 1,(matrix[0].indexOf(" KICK") - nick.length()));
      QString chan = matrix[2];
      QString kicked = matrix[3];
      QString message;
      if (raw.indexOf(" :") != -1)
        message = raw.right((raw.length() - 2) - raw.indexOf(" :"));
      emit kick(nick,mask,chan,kicked,message);
    }
    else // u mode
      emit umodeChange(matrix[0],matrix[2],raw.right((raw.length() - 2) - raw.indexOf(" :")));
  }
  bool isInt;
  int code_msg = matrix[1].toInt( &isInt );
  if( isInt ) {
    switch ( code_msg ) {
      case 001: // me es útil, así sé con qué nick entro xD
        emit ownNickChange(matrix[2]);
        ownNick = matrix[2];
        if (!chans.isEmpty()) {
          sendData("JOIN ",true);
          sendData(chans);
        }
        status = STATUS_IDLE;
        emit signedIn();
        break;
      case 254: // número de canales formados
        emit totalChans(matrix[3]);
      case 321: // chanlist begin
        handleChanlist(false);
        break;
      case 322: // chanlist
        handleChanlist(matrix[3],matrix[4],raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 323: // chanlist end
        handleChanlist(true);
        break;
      case 332: //topic
        emit topic(matrix[3],raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 333: //topic timestamp
        emit topicTime(matrix[3],matrix[4],matrix[5]);
        break;
      case 353: // names
        emit names(matrix[4], raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 366: // fin de /names
        emit namesEnd(matrix[3]);
        break;
      case 372: // texto de motd
        emit motd( raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 375: // inicio de motd
        emit motdStart( raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 376: // fin de motd
        emit motdEnd( raw.right((raw.length() - 2) - raw.indexOf(" :")));
        break;
      case 433: // nick en uso!
        getNewRandomNick();
        break;
      case 471:
        qDebug() << matrix[3] << "Cannot join channel (+l)";
        break;
      case 473:
        qDebug() << matrix[3] << "Cannot join channel (+i)";
        break;
      case 474:
        qDebug() << matrix[3] << "Cannot join channel (+b)";
        break;
      case 475:
        qDebug() << matrix[3] << "Cannot join channel (+k)";
        break;
      default:
        //qDebug() << "Numeric NO MANEJADO!" << matrix[1] << endl;
        break;
    }
  }
}