QualNet收发包过程分析(五)

接上文https://blog.csdn.net/zhang1806618/article/details/107856736

2.3 网络层

NETWORK_ReceivePacketFromMacLayer函数区分网络层协议调用相应协议处理。对IPv4协议,调用NetworkIpReceivePacketFromMacLayer()函数,该函数又直接调用NetworkIpReceivePacket()函数。在NetworkIpReceivePacket()函数中,判断是否是发送给本节点的包,如果不是,直接转发;如果是,经由背板处理,另外判断是否多播包,多播包还需转发。

void NetworkIpReceivePacket(
    Node *node,
    Message *msg,
    NodeAddress previousHopAddress,
    int incomingInterface)
{
    NetworkType netType = NETWORK_IPV4;    
    //是发送给本节点的包
    if (IsMyPacket(node, ipHeader->ip_dst) || IsIgmpPacket(node, ipHeader->ip_p))
    {        
        BOOL isMulticast = NetworkIpIsMulticastAddress(node, ipHeader->ip_dst);
        Message* sendMessage = msg;
        if (isMulticast)
        {
            sendMessage = MESSAGE_Duplicate(node, msg);
        }
        //经由背板处理
        NetworkIpSendOnBackplane(node,
                                 sendMessage,
                                 incomingInterface,
                                 CPU_INTERFACE,
                                 previousHopAddress);
        //多播包,背板处理之余还要转发
        if (isMulticast)
        {
            ForwardPacket(node, msg, incomingInterface, ANY_IP);
        }
    } 
    //不是发给本节点的包,直接转发
    else
    {
        ForwardPacket(node, msg, incomingInterface, previousHopAddress);
    }
}

ForwardPacket()函数用于转发,会进入到发送程序,此处不赘述。NetworkIpSendOnBackplane()函数在介绍发送端过程时已介绍,在无容量限制时,调用DeliverPacket()函数将数据上传至传输层;在容量限制时,调用NetworkIpUseBackplaneIfPossible()再调用DeliverPacket()函数。在DeliverPacket()函数中去除IP首部,然后根据传输层协议分别调用相应协议函数处置。

void //inline//
DeliverPacket(Node *node, Message *msg,
              int interfaceIndex, NodeAddress previousHopAddress)
{
    NetworkIpRemoveIpHeader(node, msg, &sourceAddress, &destinationAddress,
                            &priority, &ipProtocolNumber, &ttl);
    switch (ipProtocolNumber)
    {
        //上传的传输层协议
        case IPPROTO_UDP:
        {
            SendToUdp(node, msg, priority, sourceAddress, destinationAddress,
                      interfaceIndex);
            break;
        }
        case IPPROTO_TCP:
        {
            SendToTcp(node, msg, priority, sourceAddress, destinationAddress,
                      aCongestionExperienced);
            break;
        }
    }
}

以UDP协议为例,SendToUdp()函数调度传输层协议UDP事件 MSG_TRANSPORT_FromNetwork,由传输层事件处理函数处理。

void
SendToUdp(
    Node *node,
    Message *msg,
    TosType priority,
    NodeAddress sourceAddress,
    NodeAddress destinationAddress,
    int incomingInterfaceIndex)
{
    NetworkToTransportInfo *infoPtr;
    MESSAGE_SetEvent(msg, MSG_TRANSPORT_FromNetwork);
    MESSAGE_SetLayer(msg, TRANSPORT_LAYER, TransportProtocol_UDP);
    MESSAGE_SetInstanceId(msg, 0);
    MESSAGE_InfoAlloc(node, msg, sizeof(NetworkToTransportInfo));
    infoPtr = (NetworkToTransportInfo *) MESSAGE_ReturnInfo(msg);

    SetIPv4AddressInfo(&infoPtr->sourceAddr, sourceAddress);
    SetIPv4AddressInfo(&infoPtr->destinationAddr, destinationAddress);

    infoPtr->priority = priority;
    infoPtr->incomingInterfaceIndex = incomingInterfaceIndex;

    MESSAGE_Send(node, msg, PROCESS_IMMEDIATELY);
}

2.4 传输层

传输层事件处理函数TRANSPORT_ProcessEvent()根据协议UDP调用函数TransportUdpLayer(),进而根据事件 MSG_TRANSPORT_FromNetwork调用函数TransportUdpSendToApp()。在该函数中,去除UDP首部,将事件层更改为应用层,将事件更改为MSG_APP_FromTransport,进而让应用层事件处理函数处理该数据包。

void
TransportUdpSendToApp(Node *node, Message *msg)
{
    MESSAGE_SetLayer(msg, APP_LAYER, udpHdr->destPort);
    MESSAGE_SetEvent(msg, MSG_APP_FromTransport);
    MESSAGE_SetInstanceId(msg, 0);
    MESSAGE_RemoveHeader(node, msg, sizeof(TransportUdpHeader), TRACE_UDP);
    MESSAGE_Send(node, msg, TRANSPORT_DELAY);
}

2.5 应用层

应用层事件处理函数APP_ProcessEvent根据应用层协议选择相应的协议处理函数,在协议处理函数中再根据事件类型MSG_APP_FromTransport进行相应的处理。

猜你喜欢

转载自blog.csdn.net/zhang1806618/article/details/107861458