协议栈纪要

5月27日

基本上,我想要的功能都已经完成了,接下来需要做的事情就是修修补补.还有,需要写博文记录一下到底干了什么以及怎么去干.

5月24日

c语言最让人头疼的事情是指针,真的,一旦指针出了一点儿故障,你都找不到原因.我跟你说.

今天的问题最终还是解决了,原因很简单,是我的指针越界了,然后我往越界的地方写入了一点东西,今天这个玩意折腾了我一个下午.郁闷.

5月21日

现在已经基本上对这部分代码非常熟悉了,所以修改起来也得心应手,很爽.

5月20日

昨天一天改了很多代码,添加了很多代码,删除了很多代码,总之关于tcp部分的工作已经做得差不多了.我觉得努力一把,在5月底的时候完成这个简陋的该死的协议栈,还是有望的.

5月16日

最近突然有一项任务要完成,抽不出太多时间来弄协议栈啦,所以,协议栈的事情可能要延迟了,应该不会超过一个月吧,一个月后,我会继续来干的.

5月14日

造一个轮子代价昂贵,我太想吐槽这一点了,直到今天,我感觉还有非常多的事情要干,不知道一个简单的协议栈什么时候才能搞得完.

5月12日

今天改进和精简了一点代码,发现要实现一个简易的posix标准的网络函数,如bind, accept,listen等,还有一大段代码要写,而这,真是乐趣之所在,鬼知道还有多久能够弄完这个协议栈,不过,在读协议栈的实现和精简协议栈的过程中,unp的不少内容,现在已经能够读懂了,记住,是真正懂了,原来unp上一些东西我压根就不知道在讲什么,包括那些高级的部分.

5月9日

拨开云雾见青天.终于调试正确了,tap设备正常工作.今天是非常非常重要的一天,因为今天终于将苦大仇深的代码调试成功了.

5月8日

最近被tun/tap这个概念折磨得很惨,使用百度搜索了一下这个玩意,没有一篇文章将这个东西完全讲清楚了,自己对着书,对着自己的想法,鼓捣了很久,依旧不得法,我接近放弃的时候,明智地用了一下谷歌搜索,很幸运,搜到了几篇文章,将tun/tap这个概念讲清楚了,接下来的事情就好办了.

5月6日

流年不利,我发现用tun/tap实现协议栈,貌似没有很好的调试方法,特别蛋疼.或许是我还没有找到一种好的调试办法吧,今天尝试了很多,试图让实现的这个协议栈连接上外网,但是失败了,老是失败,我要重新理解一下,到底什么才是tun/tap.

大概能花在这个协议栈上的时间,只能有1个月啦,6月份开始,要立马刷题了.希望最近几天能够找到一种好的方法来将它调试成功.

5月5日

废了好大的劲,终于将昨天那个malloc,free的问题给解决了.这里我稍微记录一下思路,以便给将来引以为戒.

昨天遇到的问题是,一旦我使用malloc,然后调用free,类似于这样:

void *address = malloc(42);
free(address);  // 代码没有任何问题

立马就报类似于这样的错误,同时程序立马崩溃:

free(): invalid next size (fast):

是不是非常诡异,我昨天调试了一个晚上,愣是没有找出原因,今天想了一点小办法,终于干掉了这个bug.

事实上,上面的代码并没有错,真正的错误原因在于,我在调用上面的代码之前,已经在别的地方用malloc分配了一块内存,然后一不小心,在操纵这块内存的时候,往越界的地址写入了一些数据,此后,我调用malloc不会出问题,但是调用free有很大的几率程序会立即崩溃掉,同时会爆出上面的错误.

个人怀疑是我越界写入的那些数据覆盖了malloc分配内存时记录的一些关于内存块大小的信息,使得调用free的时候无法找到这些信息,也就无从回收内存,导致出错.八九不离十啦.

我这里试图还原一下当时的场景:

#define ETH_HDR_LEN 10
#define IP_HDR_LEN 20
#define TCP_HDR_LEN 20

struct sk_buff {
    ...
    uint32_t dlen;          // 数据的大小,不包含头部(以太网,ip,tcp头部)
    uint8_t *end;
    uint8_t *head;
    uint8_t *data;
    uint8_t *payload;
};

// skb_reserve丢弃掉前len个数据,或者说是保留前面长度为len的数据
void *
skb_reserve(struct sk_buff *skb, unsigned int len)
{
    skb->data += len;
    return skb->data;
}


void 
free_skb(struct sk_buff *skb)
{
    free(skb->head);
    free(skb);
}

struct sk_buff *
alloc_skb(unsigned int size)
{
    struct sk_buff *skb = malloc(sizeof(struct sk_buff));
    memset(skb, 0, sizeof(struct sk_buff));
    skb->data = malloc(size);    // 记录下数据
    memset(skb->data, 0, size);

    skb->refcnt = 0;
    skb->head = skb->data;       // 数据开始的地方
    skb->end = skb->data + size; // 数据结束的地方
    list_init(&skb->list);
    return skb;
}

static struct sk_buff *
tcp_alloc_skb(int optlen, int size)
{
    // optlen表示tcp首部选项的大小
    // 这里要特别注意一下,因为忘记了TCP_HDR_LEN导致出错
    // ===============================================
    int reserved = ETH_HDR_LEN + IP_HDR_LEN + /*TCP_HDR_LEN +*/ optlen + size; // 如果这里丢了一个TCP_HDR_LEN
    struct sk_buff *skb = alloc_skb(reserved);

    skb_reserve(skb, reserved); // skb->data部分留出reserved个字节
    skb->dlen = size;   // dlen表示数据的大小
    return skb;
}

void manipulate()
{
    struct sk_buff *skb = tcp_alloc_skb(0, 0);
    // 因为optlen和size都为0
    // 用一个tcphdr的结构的指针tcp获取skb中的tcp头部部分,并填入数据,其实在这里就越界了.
    ...
    // 用一个iphdr的结构的指针ip获取skb中关于ip头部部分,填入数据
    ...
    // 用一个ethhdr结构的指针eth获取skb中关于以太网头部部分,填入数据
    // 用一副示意图表示如下,其实在第一步,tcp就指向了不属于自己的内存的首部,对其进行填充之后
    // 当时没有任何问题,但是到了free_skb的时候,立马出错,我怀疑malloc函数将内存块的信息恰好填
    // 入到了tcphdr那一部分
    /*
            |-------------------|   <--- skb->head, eth
            |     ethhdr       |
            |-------------------|   <--- iphdr, ip  
            |     iphdr     |       
            |                  |
            |-------------------|   <--- skb->end, tcp
            |     tcphdr       |     bad memory 
            |                  |    
    */
    
    free_skb(skb); // 立马出错,因为在不属于你的内存部分写入了数据
}

上面的问题看似很简单,或许你会拍一拍胸膛,我绝对不会犯这种错误,但是真的当代码多了之后,估计你就不会说这样的话了,如果尝试过调试了7,8个小时,连bug的半点头绪都找不到这种绝望的话,估计你也会说--c语言呀,指针这个东西,真的需要特别小心.

5月4日

原来没有想到的一个问题是,应用程序究竟是如何同协议栈进行交流的,现在明白了,使用的是IPC机制,从昨天一直到现在,终于将unix本机通信的程序调通了.接下来就只要将三次握手调试成功就差不多了.

妈蛋,c语言的内存分配真是个大问题,调了半天不知道错在哪里,先malloc,然后free,立马出错,这玩意和玄学差不多.

5月3日

学习网络编程最好的方式,的确是摸透一个TCP IP协议栈的实现.读level-ip,结合tcp ip详解卷,再配合上手实验,个人感觉收获非常大,毕竟看到了抽象背后的东西.

越是读源代码实现,我越是觉得,真正要在linux做系统编程的话,对操作系统原理的理解是必不可少的,最好的操作系统教程,不是书本,而是源码.当然,书本比不可少,它记录了一些原理性的东西,但是源码会使我们对一些东西明白得更加透彻.xv6, ucore都是不错的教材.

=======================
这篇文章什么也不干,我就是想记录一下自己读tcp ip协议栈的实现,自己的一点感想.仅此而已.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,428评论 25 707
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,359评论 0 3
  • 每天都奔跑着 去遇见你 祈祷着 人潮 让我们相拥
    leahsu阅读 206评论 0 0
  • 何为目的?行动和努力最终要达到的境界。做任何事带着目的去做,事半功倍,达到或超越自己所想的效果。 知识萃取第二...
    icecream_29a4阅读 223评论 2 0
  • 亲爱的CC:你好! 不久前,给你买了小天才电话手表,专门给你挑选了手机号码。使用了一阵子,挺方便,不过,很快被老师...
    Leice阅读 219评论 0 1