分享
 
 
 

linuxkernel2.4.5ipv4socket层的一点解释

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

1.新建socket

函数原形:

static int inet_create(struct socket *sock, int protocol)

在net/ipv4/af_inet.c中

详细解释

static int inet_create(struct socket *sock, int protocol)

{

struct sock *sk;

struct proto *prot;

sock-state = SS_UNCONNECTED;

/* 设置状态为未连接 */

sk = sk_alloc(PF_INET, GFP_KERNEL, 1); /* 申请sock所需的内存 */

/* net/core/sock.c */

if (sk == NULL)

goto do_oom;

switch (sock-type) {

case SOCK_STREAM:

/* TCP协议 */

if (protocol && protocol != IPPROTO_TCP)

goto free_and_noproto;

protocol = IPPROTO_TCP;

prot = &tcp_prot;

/* tcp_prot定义在net/ipv4/tcp_ipv4.c */

sock-ops = &inet_stream_ops; /* 针对STREAM的socket操作 */

break;

case SOCK_SEQPACKET:

/* 不支持 */

goto free_and_badtype;

case SOCK_DGRAM:

/* UDP协议 */

if (protocol && protocol != IPPROTO_UDP)

goto free_and_noproto;

protocol = IPPROTO_UDP;

sk-no_check = UDP_CSUM_DEFAULT;

prot=&udp_prot;

/* udp_prot定义在net/ipv4/udp.c */

sock-ops = &inet_dgram_ops; /* 针对DGRAM的socket操作 */

break;

case SOCK_RAW:

/* RAW */

if (!capable(CAP_NET_RAW)) /* 判断是否有权利建立SOCK_RAW */

goto free_and_badperm;

if (!protocol)

/* protocol不能为0 */

goto free_and_noproto;

prot = &raw_prot;

/* raw_prot定义在net/ipv4/raw.c */

sk-reuse = 1;

/* 允许地址重用 */

sk-num = protocol;

sock-ops = &inet_dgram_ops; /* RAW的一些特性和DGRAM相同 */

if (protocol == IPPROTO_RAW)

sk-protinfo.af_inet.hdrincl = 1;

/* 允许自己定制ip头 */

break;

default:

goto free_and_badtype;

}

if (ipv4_config.no_pmtu_disc)

sk-protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;

else

sk-protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;

sk-protinfo.af_inet.id = 0;

sock_init_data(sock,sk);

/* 初始化一些数据 */

/* net/core/sock.c */

sk-destruct = inet_sock_destruct; /* 当销毁socket时调用inet_sock_destruct */

sk-zapped = 0;

sk-family = PF_INET;

sk-protocol = protocol;

sk-prot = prot;

sk-backlog_rcv = prot-backlog_rcv; /* prot-backlog_rcv()见各个类型的定义 */

sk-protinfo.af_inet.ttl = sysctl_ip_default_ttl; /* 设置默认ttl */

/* 修改/proc/sys/net/ipv4/ip_default_ttl */

sk-protinfo.af_inet.mc_loop = 1;

sk-protinfo.af_inet.mc_ttl = 1;

sk-protinfo.af_inet.mc_index = 0;

sk-protinfo.af_inet.mc_list = NULL;

#ifdef INET_REFCNT_DEBUG

atomic_inc(&inet_sock_nr);

#endif

if (sk-num) {

/* It assumes that any protocol which allows

* the user to assign a number at socket

* creation time automatically

* shares.

*/

sk-sport = htons(sk-num); /* 设置本地端口 */

/* Add to protocol hash chains. */

sk-prot-hash(sk);

}

if (sk-prot-init) {

int err = sk-prot-init(sk); /* 协议对socket的初始化 */

if (err != 0) {

inet_sock_release(sk);

return(err);

}

}

return(0);

free_and_badtype:

sk_free(sk);

/* 释放内存 */

return -ESOCKTNOSUPPORT;

free_and_badperm:

sk_free(sk);

return -EPERM;

free_and_noproto:

sk_free(sk);

return -EPROTONOSUPPORT;

do_oom:

return -ENOBUFS;

}

在net/core/sock.c

void sock_init_data(struct socket *sock, struct sock *sk)

{

skb_queue_head_init(&sk-receive_queue); /* 初始化3条队列 接受,发送,错误*/

skb_queue_head_init(&sk-write_queue);

skb_queue_head_init(&sk-error_queue);

init_timer(&sk-timer);

/* 初始化timer */

sk-allocation = GFP_KERNEL;

sk-rcvbuf = sysctl_rmem_default;

sk-sndbuf = sysctl_wmem_default;

sk-state = TCP_CLOSE;

sk-zapped = 1;

sk-socket = sock;

if(sock)

{

sk-type = sock-type;

sk-sleep = &sock-wait;

sock-sk = sk;

} else

sk-sleep = NULL;

sk-dst_lock

= RW_LOCK_UNLOCKED;

sk-callback_lock = RW_LOCK_UNLOCKED;

/* sock_def_wakeup(),sock_def_readable(),

sock_def_write_space(),sock_def_error_report(),

sock_def_destruct() 在net/core/sock.c */

sk-state_change = sock_def_wakeup;

sk-data_ready

= sock_def_readable;

sk-write_space

= sock_def_write_space;

sk-error_report = sock_def_error_report;

sk-destruct

=

sock_def_destruct;

sk-peercred.pid = 0;

sk-peercred.uid = -1;

sk-peercred.gid = -1;

sk-rcvlowat

= 1;

sk-rcvtimeo

= MAX_SCHEDULE_TIMEOUT; /* 设置接受,发送超时 */

sk-sndtimeo

= MAX_SCHEDULE_TIMEOUT;

atomic_set(&sk-refcnt, 1);

}

1.1 SOCK_STREAM的初始化

在net/ipv4/tcp_ipv4.c

static int tcp_v4_init_sock(struct sock *sk)

{

struct tcp_opt *tp = &(sk-tp_pinfo.af_tcp);

skb_queue_head_init(&tp-out_of_order_queue);

tcp_init_xmit_timers(sk);

tcp_prequeue_init(tp);

tp-rto

= TCP_TIMEOUT_INIT;

tp-mdev = TCP_TIMEOUT_INIT;

/* So many TCP implementations out there (incorrectly) count the

* initial SYN frame in their delayed-ACK and congestion control

* algorithms that we must have the following bandaid to talk

* efficiently to them.

-DaveM

*/

tp-snd_cwnd = 2;

/* See draft-stevens-tcpca-spec-01 for discussion of the

* initialization of these values.

*/

tp-snd_ssthresh = 0x7fffffff; /* Infinity */

tp-snd_cwnd_clamp = ~0;

tp-mss_cache = 536;

tp-reordering = sysctl_tcp_reordering;

sk-state = TCP_CLOSE;

sk-write_space = tcp_write_space; /* tcp_write_space() 在net/ipv4/tcp.c */

sk-use_write_queue = 1;

sk-tp_pinfo.af_tcp.af_specific = &ipv4_specific;

/* ipv4_specific 在net/ipv4/tcp_ipv4.c */

sk-sndbuf = sysctl_tcp_wmem[1]; /* 设置发送和接收缓冲区大小 */

sk-rcvbuf = sysctl_tcp_rmem[1]; /* sysctl_tcp_* 在net/ipv4/tcp.c */

atomic_inc(&tcp_sockets_allocated); /* tcp_sockets_allocated是当前TCP socket的数量 */

return 0;

}

SOCK_DGRAM无初始化

1.2 SOCK_RAW初始化

在net/ipv4/raw.c

static int raw_init(struct sock *sk)

{

struct raw_opt *tp = &(sk-tp_pinfo.tp_raw4);

if (sk-num == IPPROTO_ICMP)

memset(&tp-filter, 0, sizeof(tp-filter));

return 0;

}

2.Server

2.1 bind

static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)

{

struct sockaddr_in *addr=(struct sockaddr_in *)uaddr;

struct sock *sk=sock-sk;

unsigned short snum;

int chk_addr_ret;

int err;

/* If the socket has its own bind function then use it. (RAW) */

if(sk-prot-bind)

return sk-prot-bind(sk, uaddr, addr_len);

/* 只有SOCK_RAW定义了自己的bind函数 */

if (addr_len

return -EINVAL;

chk_addr_ret = inet_addr_type(addr-sin_addr.s_addr);

/* inet_addr_type返回地址的类型 */

/* 在net/ipv4/fib_frontend.c */

/* Not specified by any standard per-se, however it breaks too

* many applications when removed.

It is unfortunate since

* allowing applications to make a non-local bind solv

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有