void Imap4Analyser::analyse(const char* content, size_t length, const SessionId& sessionId) { LOG4CPLUS_TRACE(LOGGER, "********************analyse enter, content=" << content << ", length=" << length << ", sessionId=" << sessionId); // 长度至少要为最小可分析长度 if (0 == content || MIN_LENGTH > length) { LOG4CPLUS_WARN(LOGGER, "invalid packet, content error or length error"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } string str(content); // 查找第一个空格,将之前的内容视为标签 size_t tagEndPos = str.find_first_of(' '); // 未找到空格,视为无效数据 if (string::npos == tagEndPos) { LOG4CPLUS_WARN(LOGGER, "invalid packet, can't find blank character"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 标签长度为零 if (0 == tagEndPos) { LOG4CPLUS_WARN(LOGGER, "invalid packet, tag length is zero"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 得到标签 string tag = str.substr(0, tagEndPos); LOG4CPLUS_TRACE(LOGGER, "get tag, tag=" << tag); // 测试长度是否足够继续分析 if (tagEndPos + 1 >= length) { LOG4CPLUS_WARN(LOGGER, "invalid packet, content deficient"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 查找LOGIN命令 size_t cmdOrResponseBeginPos = str.find(COMMAND_LOGIN, tagEndPos + 1); // 找到LOGIN命令 if (string::npos != cmdOrResponseBeginPos && tagEndPos + 1 == cmdOrResponseBeginPos) { LOG4CPLUS_TRACE(LOGGER, "get LOGIN cmd"); // 测试长度是否足够继续分析 size_t cmdEndPos = cmdOrResponseBeginPos + COMMAND_LOGIN.size(); if (cmdOrResponseBeginPos + 2 >= length) { LOG4CPLUS_WARN(LOGGER, "invalid packet, content deficient"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 查找登录用户名 size_t userNameEndPos = str.find_first_of(' ', cmdEndPos + 2); if (string::npos == userNameEndPos) { LOG4CPLUS_WARN(LOGGER, "invalid login cmd, can't find user name"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 获取登录用户名 string userName = str.substr(cmdEndPos, userNameEndPos - cmdEndPos); LOG4CPLUS_TRACE(LOGGER, "get LOGIN user name, userName="******"removed existing sessionInfo"); } // 创建新的会话信息 SessionInfo * const sessionInfoP = new SessionInfo(); putSessionInfo(sessionId, *sessionInfoP); // 放入登录信息 CmdInfo* cmdInfoP = new CmdInfo(); cmdInfoP->setCmdId(ID_COMMAND_LOGIN); const time_t now = time(0); cmdInfoP->setStartMillis(now * 1000); // 放入命令标签 int key = PROPS_KEY_TAG; pair<int, void*> propTag(key, new string(tag)); cmdInfoP->addProperty(propTag); // 放入用户名 key = PROPS_KEY_USER_NAME; pair<int, void*> propUserName(key, new string(userName)); cmdInfoP->addProperty(propUserName); sessionInfoP->addCmd(cmdInfoP); // 设置服务端和客户端IP sessionInfoP->setServerIp(sessionId.getDestIp()); sessionInfoP->setServerPort(sessionId.getDestPort()); sessionInfoP->setClientIp(sessionId.getSourceIp()); sessionInfoP->setClientPort(sessionId.getSourcePort()); // 计算包数量和大小 sessionInfoP->setPacketsCount(1); sessionInfoP->setBytesCount(54 + length); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } LOG4CPLUS_TRACE(LOGGER, "can't find LOGIN cmd"); // 查看是否已经有相关信息,是否已经LOGIN bool contained = containsSessionInfo(sessionId); // 当前包是否为响应命令 bool isResponse = !contained; const SessionId* reverseIdP = 0; // 测试是否为响应包 if (!contained) { reverseIdP = new SessionId(sessionId.getDestIp(), sessionId.getDestPort(), sessionId.getSourceIp(), sessionId.getSourcePort(), sessionId.getProtocolId()); contained = containsSessionInfo(*reverseIdP); isResponse = contained; } // 非已知的会话包,丢弃 if (!contained) { LOG4CPLUS_WARN(LOGGER, "ignored packed, can't find sessionInfo"); LOG4CPLUS_TRACE(LOGGER, "analyse leave"); return; } // 是已知的会话包,计算大小及包数 SessionInfo * const sessionInfoP = getSessionInfo(isResponse ? *reverseIdP : sessionId); sessionInfoP->setPacketsCount((sessionInfoP->getPacketsCount() + 1)); sessionInfoP->setBytesCount(sessionInfoP->getBytesCount() + 54 + length); // 非响应包,由客户端发向服务器 if (!isResponse) { // 查找LOGINOUT命令 cmdOrResponseBeginPos = str.find(COMMAND_LOGOUT, tagEndPos + 1); // 找到登出命令 if (string::npos != cmdOrResponseBeginPos && tagEndPos + 1 == cmdOrResponseBeginPos) { LOG4CPLUS_TRACE(LOGGER, "get LOGOUT cmd"); // 放入登出信息 CmdInfo* cmdInfoP = new CmdInfo(); cmdInfoP->setCmdId(ID_COMMAND_LOGOUT); const time_t now = time(0); cmdInfoP->setStartMillis(now * 1000); // 放入命令标签 int key = PROPS_KEY_TAG; pair<int, void*> propTag(key, new string(tag)); cmdInfoP->addProperty(propTag); sessionInfoP->addCmd(cmdInfoP); } LOG4CPLUS_TRACE(LOGGER, "analyse leave"); } // 响应包,由服务器发向客户端 else { // 先查找LOGIN的返回状态,先查看标签是否一致 vector<CmdInfo*> cmds = (*(sessionInfoP->getCmds())); string* tagP = static_cast<string*> (cmds[0]->getProperty(PROPS_KEY_TAG)); bool isSameTag = *tagP == tag; // 标签一致,是期待的LOGIN的响应 if (isSameTag) { // 查找登录的命令响应 const size_t responseBeginPos = tagEndPos + 1; int statusId = ID_RESPONSE_LOGIN_UNKNOW; // 尝试OK响应 cmdOrResponseBeginPos = str.find(RESPONSE_LOGIN_OK, responseBeginPos); if (string::npos != cmdOrResponseBeginPos && cmdOrResponseBeginPos == responseBeginPos) { statusId = ID_RESPONSE_LOGIN_OK; } else { // 尝试NO响应 cmdOrResponseBeginPos = str.find(RESPONSE_LOGIN_NO, responseBeginPos); if (string::npos != cmdOrResponseBeginPos && cmdOrResponseBeginPos == responseBeginPos) { statusId = ID_RESPONSE_LOGIN_NO; } else { // 尝试BAD响应 cmdOrResponseBeginPos = str.find(RESPONSE_LOGIN_BAD, responseBeginPos); if (string::npos != cmdOrResponseBeginPos && cmdOrResponseBeginPos == responseBeginPos) { statusId = ID_RESPONSE_LOGIN_BAD; } } } const time_t now = time(0); cmds[0]->setResponseMillis(now * 1000); cmds[0]->setStatusId(statusId); LOG4CPLUS_TRACE(LOGGER, "got LOGIN cmd response, statusId=" << statusId); } // 查找 LOGOUT 命令的响应 else { // 是否已经收到LOGOUT命令 if (2 == cmds.size()) { tagP = static_cast<string*> (cmds[1]->getProperty(PROPS_KEY_TAG)); // 查看标签是否一致 isSameTag = *tagP == tag; size_t responseBeginPos = tagEndPos + 1; if (!isSameTag && GENERAL_TAG == tag && responseBeginPos < length) { string newTag("\r\n"); newTag.append(*tagP); newTag.append(" "); newTag.append(RESPONSE_LOGOUT_OK); size_t tmp = str.find(newTag, responseBeginPos); isSameTag = string::npos != tmp; if (isSameTag) { responseBeginPos = tmp + 3 + tagP->size(); } // 再尝试BAD if (!isSameTag) { string newTag("\r\n"); newTag.append(*tagP); newTag.append(" "); newTag.append(RESPONSE_LOGOUT_BAD); size_t tmp = str.find(newTag, responseBeginPos); isSameTag = string::npos != tmp; if (isSameTag) { responseBeginPos = tmp + 3 + tagP->size(); } } } // 标签一致,是期待的LOGOUT的响应 if (isSameTag) { // 查找的登出命令响应 int statusId = ID_RESPONSE_LOGOUT_BAD; // 尝试OK响应 cmdOrResponseBeginPos = str.find(RESPONSE_LOGOUT_OK, responseBeginPos); if (string::npos != cmdOrResponseBeginPos && responseBeginPos == cmdOrResponseBeginPos) { statusId = ID_RESPONSE_LOGOUT_OK; } const time_t now = time(0); cmds[1]->setResponseMillis(now * 1000); cmds[1]->setStatusId(statusId); LOG4CPLUS_TRACE(LOGGER, "got LOGOUT cmd response, statusId=" << statusId); log(sessionInfoP); removeSessionInfo(*reverseIdP); } } } delete reverseIdP; LOG4CPLUS_TRACE(LOGGER, "analyse leave"); } }
// ============================================================================ // CWidgetEntry::InternalizeXmlL() // read from persistent storage(file) // // @since 5.0 // ============================================================================ // void CWidgetEntry::InternalizeXmlL( RFs& aFileSession, xmlDocPtr aDoc, xmlNode* n, CWidgetRegistryXml* aXmlProcessor ) { // <prop>name<val>value<type>typename</type></val></prop> // // prop subtree traversal assumes strict adherence to the // prototype structure, otherwise code leaves with corrupt code for ( ; n; ) { // permit some non element stuff (comment, whitespace...) before <prop> while ( n && ( n->type != XML_ELEMENT_NODE ) ) { n = n->next; } if ( NULL == n ) { for (TInt i = iPropertyValues.Count(); i < EWidgetPropertyIdCount; i++) { CWidgetPropertyValue* val = CWidgetPropertyValue::NewL(); CleanupStack::PushL(val); iPropertyValues.AppendL( val ); CleanupStack::Pop(); // val } return; } TPtrC8 propTag( n->name ); if ( 0 != propTag.Compare( KXmlPropTag() ) ) { // TODO unrecognized subtree? return; } // TODO validate n->children != NULL and type XML_TEXT_NODE HBufC* name; aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &name ); // get value array index (TWidgetPropertyId) for name TPtr namePtr( name->Des() ); TInt propId = aXmlProcessor->GetPropertyId( namePtr ); delete name; name = NULL; if ( EWidgetPropertyIdInvalid == propId ) { User::Leave( KErrNoMemory ); } for (TInt i = iPropertyValues.Count(); i <= propId; i++) { CWidgetPropertyValue* val = CWidgetPropertyValue::NewL(); CleanupStack::PushL(val); iPropertyValues.AppendL( val ); CleanupStack::Pop(); // val } n = n->children->next; // down to val if ( NULL == n ) { User::Leave( KErrCorrupt ); } TPtrC8 valTag( n->name ); if ( 0 != valTag.Compare( KXmlValTag() ) ) { User::Leave( KErrCorrupt ); } if (propId >= EWidgetPropertyIdCount) // unsupported property { HBufC* value = NULL; if (n->children) { aXmlProcessor->GetTextContentAsStringL( aFileSession, aDoc, n->children, &value ); } else { value = KNullDesC().AllocL(); } (*this)[propId].iValue.s = value; (*this)[propId].iType = EWidgetPropTypeBlob; n = (n->parent)->next; // up two and next sibling continue; } // TODO validate n->children != NULL and type XML_TEXT_NODE HBufC* value; aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &value ); CleanupStack::PushL( value ); n = n->children->next; // down to type if ( NULL == n ) { User::Leave( KErrCorrupt ); } TPtrC8 typeTag( n->name ); if ( 0 != typeTag.Compare( KXmlTypeTag() ) ) { User::Leave( KErrCorrupt ); } // TODO validate n->children != NULL and type XML_TEXT_NODE HBufC* type; aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &type ); CleanupStack::PushL( type ); // now have: name, value, type // convert type string to TWidgetPropertyType // // assume void/unknown is not put in XML format so anything // not recognized should be handled like other unrecognized // subtree TWidgetPropertyType typeEnum = EWidgetPropTypeUnknown; if ( 0 == type->Des().Compare( KXmlDataTypeBool() ) ) { typeEnum = EWidgetPropTypeBool; } else if ( 0 == type->Des().Compare( KXmlDataTypeInt() ) ) { typeEnum = EWidgetPropTypeInt; } else if ( 0 == type->Des().Compare( KXmlDataTypeString() ) ) { typeEnum = EWidgetPropTypeString; } else if ( 0 == type->Des().Compare( KXmlDataTypeUid() ) ) { typeEnum = EWidgetPropTypeUid; } CleanupStack::PopAndDestroy( type ); // TODO handle unknown type due to future extensions: add prop // subtree to list of unrecognized subtrees // set prop according to type switch ( typeEnum ) { case EWidgetPropTypeBool: if ( 0 == value->Des().Compare( _L("0") ) ) { (*this)[propId].iValue.i = 0; } else { (*this)[propId].iValue.i = 1; } break; case EWidgetPropTypeInt: { TLex toInt( value->Des() ); TInt k; if ( KErrNone != toInt.Val( k ) ) { User::Leave( KErrCorrupt ); } (*this)[propId].iValue.i = k; } break; case EWidgetPropTypeString: (*this)[propId].iValue.s = value; break; case EWidgetPropTypeUid: { TLex toUid( value->Des() ); TInt u; if ( KErrNone != toUid.Val( u ) ) { User::Leave( KErrCorrupt ); } (*this)[propId].iValue.uid = TUid::Uid( u ); } break; }; (*this)[propId].iType = typeEnum; CleanupStack::Pop( value ); if ( EWidgetPropTypeString != typeEnum ) { delete value; } n = ((n->parent)->parent)->next; // up two and next sibling } }