下面的代码是实现数据包的有效性检验,先调用函数validateMessage来检验接收数据缓冲区里是否有效的数据包,然后调用getMessageName函数来查看是否属于这个环路的数据包,最后判断数据包是否值得信任的或者是否禁止接收的数据。
#159
// UseCircuitCode can be a valid, off-circuit packet.
#160
// But we don't want to acknowledge UseCircuitCode until the circuit is
#161
// available, which is why the acknowledgement test is done above. JC
#162
下面检验数据包是否有效。
#163
valid_packet = mTemplateMessageReader->validateMessage(
#164
buffer,
#165
receive_size,
#166
host);
#167
#168
// UseCircuitCode is allowed in even from an invalid circuit, so that
判断这个数据包是否属于这个环路。
#169
// we can toss circuits around.
#170
if(
#171
valid_packet &&
#172
!cdp &&
#173
(mTemplateMessageReader->getMessageName() !=
#174
_PREHASH_UseCircuitCode))
#175
{
#176
logMsgFromInvalidCircuit( host, recv_reliable );
#177
clearReceiveState();
#178
valid_packet = FALSE;
#179
}
#180
判断数据包是否值得信任。
#181
if(
#182
valid_packet &&
#183
cdp &&
#184
!cdp->getTrusted() &&
#185
mTemplateMessageReader->isTrusted())
#186
{
#187
logTrustedMsgFromUntrustedCircuit( host );
#188
clearReceiveState();
#189
#190
sendDenyTrustedCircuit(host);
#191
valid_packet = FALSE;
#192
}
#193
判断数据包是否属于禁止接收的。
#194
if (
#195
valid_packet &&
#196
mTemplateMessageReader->isBanned(cdp && cdp->getTrusted()))
#197
{
#198
llwarns << "LLMessageSystem::checkMessages "
#199
<< "received banned message "
#200
<< mTemplateMessageReader->getMessageName()
#201
<< " from "
#202
<< ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ")
#203
<< host << llendl;
#204
clearReceiveState();
#205
valid_packet = FALSE;
#206
}
#207
这个数据包是有效的,下面就开始读取数据包里面的内容,也就是通过消息模板来解释数据,获取所有的信息。
#208
if( valid_packet )
#209
{
#210
logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
#211
#212
valid_packet = mTemplateMessageReader->readMessage(buffer, host);
#213
}
#214
#215
// It's possible that the circuit went away, because ANY message can disable the circuit
#216
// (for example, UseCircuit, CloseCircuit, DisableSimulator). Find it again.
#217
cdp = mCircuitInfo.findCircuit(host);
#218
#219
if (valid_packet)
#220
{
#221
// enable this for output of message names
#222
//llinfos << "< /"" << mTemplateMessageReader->getMessageName()
#223
//<< "/"" << llendl;
#224
#328
#329
mPacketsIn++;
#330
mBytesIn += mTrueReceiveSize;
#331
#332
// ACK here for valid packets that we've seen
#333
// for the first time.
下面通过判断这个数据包是否需要可靠性控制,如果需要就加到回应控制里面。
#334
if (cdp && recv_reliable)
#335
{
#336
// Add to the recently received list for duplicate suppression
#337
cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs();
#338
#339
// Put it onto the list of packets to be acked
#340
cdp->collectRAck(mCurrentRecvPacketID);
#341
mReliablePacketsIn++;
#342
}
#343
}
#344
else
#345
{
#346
if (mbProtected && (!cdp))
#347
{
#348
llwarns << "Invalid Packet from invalid circuit " << host << llendl;
#349
mOffCircuitPackets++;
#350
}
#351
else
#352
{
#353
mInvalidOnCircuitPackets++;
#354
}
#355
}
#356
#357
// Code for dumping the complete contents of a message
#358
// delete [] zero_unexpanded_buffer;
#359
}
#360
} while (!valid_packet && receive_size > 0);
#361
#362
F64 mt_sec = getMessageTimeSeconds();
#363
// Check to see if we need to print debug info
#364
if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq)
#365
{
#366
dumpCircuitInfo();
#367
mCircuitPrintTime = mt_sec;
#368
}
#369
#370
if( !valid_packet )
#371
{
#372
clearReceiveState();
#373
}
#374
#375
return valid_packet;
#376 }
消息解包的实现,首先要做的任务,就是判断数据包是否有效,如果无效的数据包就需要丢掉,这样也可以提高网络的安全性,也可以丢掉错误的数据包引起的其它错误。最后使用消息模板实现数据的解释,获取每个字段所表达的意思。
//蔡军生 2008/4/10 QQ:9073204 深圳