示例#1
0
文件: ccn.cpp 项目: LXiong/ccn
void AppLayerCCNHost(Node* node, Message* msg) {
  NodeData* nodeData;
  nodeData = (NodeData*)node->appData.nodeData;

  switch(msg->eventType) 
  {
  /*//fujiwara//
   * 1. 移動を検知したらMR(interest)を作成してPoAとHOMEにおくる
   * 2. MR(data)を受け取ったら
   * 		さらに分岐
  case hand_over_kenchi //やることを書く
  {
      clocktype send_delayTime;
          uint32_t chunk_num;
          map<uint32_t, clocktype>::iterator it;
          uint32_t next_msgName = global_node_data->return_MsgName();
          uint32_t end_chunk_num = next_msgName % 40 + 10;

          CcnMsg* ccnMsg;
            ccnMsg = new CcnMsg();
            ccnMsg->resent_times = 0;
            ccnMsg->ccn_method = DEFAULT;
            ccnMsg->msg_type = Interest;
            ccnMsg->msg_name = next_msgName; //msg_nameはよくわからない 多分解析のときにわかりやすくする狙いか?
            ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
            ccnMsg->EncodeFullNameMsg();
            ccnMsg->sender_node_id = node->nodeId;    // node->nodeid = このメッセージを送るノードのID
            ccnMsg->source_node_id = source_node_id;  //ここを変更 source_node_id = 送信先ノード(現状サーバが一個しかとれない仕様……)
            ccnMsg->payload_length = 30; //ペイロードはヘッダを除いたデータ部分の大きさ
            ccnMsg->hops_limit = 20;
            ccnMsg->content_type = CommonData;
            ccnMsg->end_chunk_num = end_chunk_num;
            ccnMsg->interest_genTime = node->getNodeTime();
            ccnMsg->data_genTime     = node->getNodeTime();

            nodeData->set_lastChunkNum(ccnMsg); //chunkの最後の値を記録 よくわからない 必要?
            nodeData->reqMapInput(node, ccnMsg); //msg_full_nameとノードのシミュレーション時間のペアを記録する
            nodeData->fibSend_DEFAULT(node, ccnMsg);//送信
            nodeData->make_reTransMsg(node, ccnMsg);//再送の話 よくわからない 必要か?
  }*/
    case MSG_APP_FromTransDataReceived: // データ受け取り時
    {
      TransportToAppDataReceived *openResult;
      openResult = (TransportToAppDataReceived*) MESSAGE_ReturnInfo(msg);
      APP_TcpCloseConnection(node, openResult->connectionId);

      // msgからccnメッセージを取得
      // ccnメッセージを処理
      // データ送信の場合、TCP接続要求を送る

      // msgのキーからccnメッセージを取り出す
      CcnMsg* ccnMsg;
      ccnMsg = nodeData->BufferRetrieve_Host(node, msg);

      Node* remote_node;
      NodeData* remote_nodeData;

      remote_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, ccnMsg->previous_node_id);
      remote_nodeData = (NodeData*)remote_node->appData.nodeData;

      // パケットロストによる取得エラー
      if(nodeData->node_role + remote_nodeData->node_role == CLIENT + RELAY_NODE) {
        if((rand() * 100.0) < (nodeData->error_rate * RAND_MAX)) {
          //printf("packet lost occured at %d->%d\n", remote_node->nodeId, node->nodeId);
          //nodeData->statData->packet_lostTimes++;
          if(ccnMsg->ccn_method == PROPOSAL && 
              (ccnMsg->msg_type == Interest || ccnMsg->msg_type == Data)){
          } else if(ccnMsg->ccn_method == PRIOR) {
            nodeData->statData->packet_lostTimes++;  // this is not lost but unacquired
            break;
          } else {
            break;
          }
        }
      }

      nodeData->StatisticalInfo_recvCcnMsg(node, ccnMsg);

      // ホップカウント(loop検出用)
      if(!ccnMsg->checkHopCount()) {
        printf("hop count is over\n");
        break;
      }

      switch(ccnMsg->ccn_method) 
      {

        case DEFAULT:
        case DEFAULT_FAST:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              // ソースノードまで転送
              // PITに名前を記録(msg_full_name)
              // ソースノードならDataパケットを返送
              // 返送する際はPITを参照
              
              if(nodeData->pitInsert_DEFAULT(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(nodeData->csSend(node, ccnMsg) == true) {
                // キャッシュヒット
                if(ccnMsg->content_type == CommonData) {
                  nodeData->StatisticalInfo_cacheHit(node, ccnMsg);
                }
                break;
              }

              // ソースノード到着
              if(ccnMsg->source_node_id == node->nodeId) {
                // InterestをDataに変換
                nodeData->convertInterest_intoData(ccnMsg);

                // Dataの送信時間設定
                clocktype send_delayTime;

                if(ccnMsg->content_type == VideoData) {
                  map<uint32_t, clocktype>::iterator it;
                  it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                  send_delayTime = it->second - node->getNodeTime();
                } else {
                  send_delayTime = 0;
                }

                // PITで設定時間に則った送信
                if(send_delayTime < 0) {
                  nodeData->pitSend_DEFAULT(node, ccnMsg);
                } else {
                  nodeData->pitSend_DEFAULT(node, ccnMsg, send_delayTime);
                }
              }
              else {
                // FIBによるフォワーディング
                nodeData->fibSend_DEFAULT(node, ccnMsg);
              }
              break;
            } // Interest

            case Data:
            {
              //if(ccnMsg->content_type == CommonData) {
              //  nodeData->statData->commonPacket_recv++;
              //  nodeData->statData->commonPacketSize_recv += ccnMsg->payload_length;
              //} else if(ccnMsg->content_type == VideoData) {
              //  nodeData->statData->videoPacket_recv++;
              //  nodeData->statData->videoPacketSize_recv += ccnMsg->payload_length;
              //}

              if(nodeData->reqMapSearch(node, ccnMsg)) {
                if(ccnMsg->content_type == CommonData) {
                  nodeData->statData->request_commonPacket_recv++;
                  nodeData->statData->request_commonPacketSize_recv += ccnMsg->payload_length;
                } else if(ccnMsg->content_type == VideoData) {
                  nodeData->statData->request_videoPacket_recv++;
                  nodeData->statData->request_videoPacketSize_recv += ccnMsg->payload_length;
                }
                
                // PROPOSAL再送での誤爆回避
                if(nodeData->ccn_method == PROPOSAL) {
                  if(ccnMsg->content_type == VideoData) {
                    nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                    nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                    delete ccnMsg;
                    break;  
                  }
                }

                // 再送パケットは次のパケットを要求しないため、ここで終了
                if(ccnMsg->resent_times > 0) {
                  if(ccnMsg->content_type == VideoData) {
                    if(nodeData->ccn_method == DEFAULT) {
                      nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                      nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                      delete ccnMsg;
                      break;
                    }
                    else if(nodeData->ccn_method == DEFAULT_FAST) {
                      nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                      nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                      delete ccnMsg;
                      break;
                    }
                  }
                }
                // 未取得chunkを取得
                if(nodeData->ccn_method == DEFAULT_FAST) {
                  if(ccnMsg->content_type == VideoData) {
                    if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) {

                      CcnMsg* t_ccnMsg;
                      t_ccnMsg = nodeData->NewCcnMsg(ccnMsg);
                      t_ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1;
                      t_ccnMsg->EncodeFullNameMsg();
                      t_ccnMsg->payload_length = 30;
                      t_ccnMsg->resent_times = 1;
                      t_ccnMsg->msg_type = Interest;
                      t_ccnMsg->hops_limit = 20;

                      nodeData->reqMapSearch(node, t_ccnMsg);
                      nodeData->reqMapInput(node, t_ccnMsg);

                      nodeData->Cancel_reTransMsg(node, t_ccnMsg->msg_full_name);
                      nodeData->make_reTransMsg(node, t_ccnMsg);

                      Node* source_node;
                      map<uint32_t, clocktype>::iterator it;
                      source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id);
                      nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData;
                      NodeData* source_nodeData;
                      source_nodeData = nodeData->source_nodeData;

                      it = source_nodeData->dataGenerateTime_map.find(t_ccnMsg->msg_chunk_num);
                      t_ccnMsg->data_genTime = it->second;

                      nodeData->set_windowSize(node, t_ccnMsg);
                      nodeData->fibSend(node, t_ccnMsg);
                    }
                  }
                }
                nodeData->release_windowSize(node, ccnMsg);

                nodeData->set_lastRecvMsg(ccnMsg);
                nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name);
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 

                if(ccnMsg->end_chunk_num < nodeData->return_lastChunkNum(ccnMsg) + 1) {
                  delete ccnMsg;
                  break;
                }


                // クライアントにData到着
                ccnMsg->msg_type = Interest;
                ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1;
                ccnMsg->EncodeFullNameMsg();
                ccnMsg->resent_times = 0;
                ccnMsg->payload_length = 30;
                ccnMsg->hops_limit = 20;
                ccnMsg->interest_genTime = node->getNodeTime();

                map<uint32_t, clocktype>::iterator it;
                it = nodeData->source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                ccnMsg->data_genTime = it->second;

                nodeData->set_lastChunkNum(ccnMsg);
                nodeData->set_windowSize(node, ccnMsg);
                nodeData->make_reTransMsg(node, ccnMsg);
                nodeData->reqMapInput(node, ccnMsg);
                nodeData->fibSend(node, ccnMsg);

                break;
              }
              nodeData->csInsert_DEFAULT(node, ccnMsg);
              nodeData->pitSend_DEFAULT(node, ccnMsg);
              break;
            }

            default:
            {
              ERROR_ReportError("Undefined msg type\n");
            }
          }
          break;
        }

        case PRIOR:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              // ソースノードまで転送
              // PITに名前を記録(msg_name)
              // ソースノードならDataパケットを返送
              // またDataパケットを一定時間ごとに生成・転送
              // 返送する際はPITを参照
              if(nodeData->csSend(node, ccnMsg) == true) {
                // キャッシュヒット
                nodeData->StatisticalInfo_cacheHit(node, ccnMsg);
                break;
              }

              if(nodeData->pitInsert_PRIOR(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(ccnMsg->source_node_id == node->nodeId) {
                nodeData->convertInterest_intoData(ccnMsg);
                nodeData->set_lastChunkNum(ccnMsg);
                APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_DATA_SEND_PKT, 0 * MILLI_SECOND);
              }
              else {
                nodeData->fibSend_PRIOR(node, ccnMsg);
              }

              break;
            }

            case Data:
            {
              if(nodeData->reqMapSearch_PRIOR(node, ccnMsg)) {
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                delete ccnMsg;
                break;
              }
              nodeData->pitSend_PRIOR(node, ccnMsg);
              break;
            }

            default:
              ERROR_ReportError("Undefined msg type\n");
          }
          break;
        }

        case PROPOSAL:
        {
          switch(ccnMsg->msg_type) {
            case Interest:
            {
              nodeData->fibModInsert(node, ccnMsg, ccnMsg->previous_node_id);
              if(nodeData->pitInsert_PROPOSAL(node, ccnMsg)) {
                // PITで登録済み
                delete ccnMsg;
                break;
              }

              if(ccnMsg->source_node_id == node->nodeId) {
                nodeData->set_lastChunkNum(ccnMsg);
                nodeData->convertInterest_intoData(ccnMsg);
                nodeData->pitSend_PROPOSAL(node, ccnMsg);
                // プッシュ配信登録
                APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_fakeINTEREST_SEND_PKT, 0 * MILLI_SECOND);
              }
              else {
                nodeData->fibSend_PROPOSAL(node, ccnMsg);
              }
              break;
            }

            case Data:
            {
              if(nodeData->reqMapSearch(node, ccnMsg)) {
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 

                // プッシュ配信登録済みクライアントであることを記録
                nodeData->reqModMapInput(node, ccnMsg);
                delete ccnMsg;
                break;
              }
              nodeData->pitSend_PROPOSAL(node, ccnMsg);

              break;
            }

            case fakeInterest:
            {
              nodeData->pitModInsert(node, ccnMsg);
              nodeData->csModInsert(node, ccnMsg);
if(nodeData->node_role == CLIENT)
if(ccnMsg->msg_name != msg_videoData_name + node->nodeId%3)
    printf("[node%d][msg%lu] fuckfuckfuck %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num);

              if(nodeData->reqModMapSearch(node, ccnMsg)) { // クライアント到着
                nodeData->recvRequestData(node, ccnMsg);  // Statistical data 
                nodeData->recvModMapInsert(node, ccnMsg);

                nodeData->convertFakeInterest_intoFakeData(ccnMsg);
                nodeData->pitModSend(node, ccnMsg);

                // 未取得chunkを取得
                if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) {
                  CcnMsg* ccnMsg;
                  ccnMsg = new CcnMsg();
                  ccnMsg->resent_times = 1;
                  ccnMsg->ccn_method = DEFAULT;
                  ccnMsg->msg_type = Interest;
                  ccnMsg->msg_name = msg_videoData_name + node->nodeId % 3;
                  ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1;
                  ccnMsg->EncodeFullNameMsg();
                  ccnMsg->sender_node_id = node->nodeId;
                  ccnMsg->source_node_id = source_node_id;
                  ccnMsg->payload_length = 30;
                  ccnMsg->hops_limit = 20;
                  ccnMsg->interest_genTime = node->getNodeTime();
                  ccnMsg->content_type = VideoData;
                  ccnMsg->end_chunk_num = UINT16_MAX;

                  Node* source_node;
                  map<uint32_t, clocktype>::iterator it;
                  source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id);
                  nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData;
                  NodeData* source_nodeData;
                  source_nodeData = nodeData->source_nodeData;

                  it = source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num);
                  ccnMsg->data_genTime = it->second;

                  nodeData->reqMapSearch(node, ccnMsg);
                  nodeData->set_windowSize(node, ccnMsg);
                  nodeData->reqMapInput(node, ccnMsg);
                  nodeData->make_reTransMsg(node, ccnMsg);
                  nodeData->fibSend(node, ccnMsg);
                } else if (ccnMsg->msg_chunk_num == nodeData->return_lastRecvMsg(ccnMsg) + 1){
                  //printf("Got actual packet\n");
                } else {
                }
                nodeData->set_lastRecvMsg(ccnMsg);
                break;
              }


              if(nodeData->fibModSend(node, ccnMsg)) {
                delete ccnMsg;
                break;
              }
              break;
            }

            case fakeData:
            {
              // クライアントにデータ到着
              if(ccnMsg->source_node_id == node->nodeId) {
                delete ccnMsg;
                break;
              }

              nodeData->pitModSend(node, ccnMsg);
              break;
            }

            default:
              ERROR_ReportError("Undefined msg type\n");
          }
          break;
        }

        default:
          ERROR_ReportError("Undefined ccn_method\n");
      }
      break;
    }

    case MSG_APP_FromTransOpenResult:   // TCPでpassive open処理が終了
      //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId);
      break;
    case MSG_APP_FromTransListenResult: // コネクション要求待機状態を確立
      //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId);
      break;

    case MSG_APP_TimerExpired: 
    {  
      AppTimer* timer;
      timer = (AppTimer *)MESSAGE_ReturnInfo(msg);
      switch(timer->type) {
        case APP_TIMER_RE_SEND_PKT:
          nodeData->send_reTransMsg(node, timer->connectionId);
        break;
      }
      break;
    }
    case MSG_APP_FromTransCloseResult:
      break;
    default:
      printf("msg->eventType = %d\n", msg->eventType);
      ERROR_ReportError("msg->eventType error: undefined eventType\n");
  }
  MESSAGE_Free(node, msg);
}