- 论坛徽章:
- 0
|
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 |
|