nfd-c添加ACK包
发送兴趣包返回数据包的代码在forwarder.c中,forwarder.c实际上包含六个函数,on_incoming_interest,onContentStoreMiss,onContentStoreHit,onOutgoingInterest,onIncomingData,onOutgoingData.
如果想要加入ACK包,应该添加两个函数,需要新添加一个包类型,ack类型的包,tlv如何编码和解码ack包,face部分应该添加一个send_ack方法。
ACK的逻辑和data包的逻辑应该是一样的,分为两部分,首先on_incoming_interest对兴趣包进行解析,如果在CS找到了与兴趣包匹配的数据包,调用on_contentstore_hit,直接通过接口返回数据包,这时候应该同时加上ACK包。
1 | static void on_contentstore_hit(pit_entry_t *pit_entry, struct data_t *data, struct face_t *face) |
否则应该调用on_contentstore_miss,首先将interest和face添加或者更新到PIT中,然后通过on_outgoing_interest转发兴趣包。on_outgoing_interest主要根据FIB找到下一跳的faceid,对所有可行的下一跳的face都在PIT中添加新的条目,并向这些face转发兴趣包。接着这些face又会通过on_incoming_interest继续判断,直到可以在CS中找到data包。
数据包部分主要包括on_incoming_data和on_outgoing_data。on_incoming_data首先会查PIT中有没有data对应的名字,若果没有输出"NO pit record",实际上相当于数据包是unsolicited不请自来的。如果PIT有,就应该将数据包插入到CS中以便后续使用。然后删除这个PIT条目,然后执行on_outgoing_data转发数据包。如果到期时间大于当前时间,就将data发送到对应端口,这里同样有send_data,这里也应该加上send_ack
1 | static void on_outgoing_data(pit_entry_t *pit_entry, struct data_t *data) |
添加NACK包
首先在face中添加send_nack()函数,当接口需要发送nack时调用此函数
1 | void send_nack(struct face_t *face, struct Nack *nack) { |
然后对on_outgoing_interest函数进行修改,原来是找不到路由直接输出no route,现在是进入on_outgoing_nack()函数,如果fib中没有,或者fib有但是没有下一跳都会进入on_outgoing_nack()函数。
1 | static void on_outgoing_interest(struct interest_t *interest, pit_entry_t *pit_entry) |
on_outgoing_nack()函数:查找PIT的请求端口,然后发送nack包。
1 | //新加的 |
on_incoming_nack()函数,也是模仿了on_incoming_data()。首先找到nack中对应的interest的名字,和PIT中的名字进行对比,如果没有则直接return,如果有就删除PIT表中的条目。
1 | void on_incoming_nack(struct Nack *nack, struct face_t *face) |
在main()函数中的handle_msg函数中应该加入一个nack的分支
1 | else if(type == TLV_Nack) |
此外,还需要对app_face进行修改,增加收到nack包的处理,实际上是PIT去调用on_nack回调,回调写在tools/app的各个应用模块中。
1 | //app-face的修改 |
应用层每个程序当用到express_interest时都需要新添一个on_nack回调用来处理返回的nack包。
1 | void on_nack(const struct Nack *nack, void *userdata) |
发送端直接没有路就会进入app_face的process_events的disconnect管道