免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 819 | 回复: 0
打印 上一主题 下一主题

cipe主要实现函数之cipe_sendmsg详解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-09 10:46 |只看该作者 |倒序浏览
cipe的基本原理和相关内容见另一篇学习笔记.
cipe_sendmsg为sock.c中的主要函数,此函数专门用于密钥交换报文的发送.

/*
*函数名:cipe_sendmsg
*函数用途:密钥交换报文的发送函数
*/
int cipe_sendmsg(
#ifdef LINUX_25
    struct kiocb *iocb,
#endif
    struct sock *sock, struct msghdr *msg
#ifdef LINUX_25
    , size_t len
#else
    , int len
#endif
#ifndef LINUX_21
    , int nonblock, int flags
#endif
    )
{
    struct msghdr mymsg;
    struct iovec myio[2];
    struct sockaddr_in sa;
    struct sockshdr sh;
    int e, n=0, ivs;/*ivs为IV的大小,IV是初始化变量,加密用的*/
    unsigned char buf[KEYXCHGBLKMAX];
    /* init struct cipe *c based on struct sock *sk */
    /* 调用完SOCKTOC后,c指向sock对应的cipe */
    SOCKTOC("cipe_sendmsg",sock,c);
    /*返回key的大小*/
    ivs=crypto_tfm_alg_ivsize(c->key);
        /*MSG_OOB为tcp的外带数据*/
    if (!(c->flags&CIPF_HAVE_KEY) && !(msg->msg_flags&MSG_OOB))
        return -EINVAL;
    if (len>KEYXCHGBLKMAX-ivs)
    return -EMSGSIZE;
    /* weak but fast PRNG, used for padding only 应该是跟加密相关的,不太知道用途*/
    cipe_prnpad(buf, sizeof(buf));
   /* 将存储在参数msg中的密钥交换报文(明文)复制到buf+ivs处,从buf到buf+ivs-1处存储IV */
    memcpy_fromiovec(buf+ivs, msg->msg_iov, len);
    len+=ivs;
    if (!(msg->msg_flags&MSG_OOB)) {
    if (buf[ivs]>=CT_DUMMY) {
     buf[KEYXCHGTSPOS-1]='\0';
    } else {
     if (lenKEYXCHGBLKMIN)
        return -EINVAL;
    }
    }
    (*(__u32 *)(buf+KEYXCHGTSPOS))=htonl(CURRENT_TIME_SEC); /* timestamp */
    /*如果msg的类型为MSG_OOB,则置IV全零*/
    if (msg->msg_flags&MSG_OOB) {
    memset(buf, 0, ivs);
    } else {
  /*如果不是MSG_OOB,则对净荷的长度进行随即填充,目的是使密钥交换报文的长度不固定以防止对其进行解析*/
    len=KEYXCHGBLKMIN+buf[sizeof(buf)-1]; /* random */
    cipe_encrypt(c, buf, (int*)&len, TW_NEWKEY);
    }
    sa.sin_family=AF_INET;
    sa.sin_addr.s_addr=c->peeraddr;
    sa.sin_port=c->peerport;
    if (c->sockshost) {
    /* Prepend a socks header. */
    memset(&sh, 0, sizeof(sh));
    sh.atyp=1;
    sh.dstaddr=c->sockshost;
    sh.dstport=c->socksport;
    myio[n].iov_base=&sh;
    myio[n].iov_len=sizeof(sh);
    ++n;
    }
    myio[n].iov_base=&buf;
    myio[n].iov_len=len;
    if (c->sockshost)
        len+=sizeof(struct sockshdr);
    /* mymsg=*msg; */
    /*构造最后要发送的报文,即加密后了的报文*/
    mymsg.msg_name=&sa;
    mymsg.msg_namelen=sizeof(sa);
    mymsg.msg_iov=myio;
    mymsg.msg_iovlen=n+1;
    /* just to be sure */
    mymsg.msg_control=NULL;
    mymsg.msg_controllen=0;
    mymsg.msg_flags=0;
    /* Call the real thing. Pretend this is user space segment. */
    {
        mm_segment_t fs=get_fs();
        set_fs(get_ds());
        dprintk(DEB_KXC, (KERN_INFO "%s: real sendmsg len %ld text=%04x...\n",
                          c->dev->name, (long)len,
                          ntohs(*((unsigned short *)(myio[n].iov_base)))));
#ifdef LINUX_25
        e=c->udp_prot->sendmsg(NULL, sock, &mymsg, len);
#else
#ifdef LINUX_21
        e=c->udp_prot->sendmsg(sock, &mymsg, len);
#else
                /*通过udp的发送函数发送出去,即通过cipe_xmit发送出去*/
        e=c->udp_prot->sendmsg(sock, &mymsg, len, nonblock, flags);
#endif
#endif
        set_fs(fs);
    }
    return e;
}

ps:e文为源代码自带注释,c文为自己对代码的理解.
如有错误,希望及时指正,不胜感激.


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/83905/showart_1687237.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP