📄 sock.c
字号:
1 /*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * SOCK - AF_INET protocol family socket handler.
7 *
8 * Version: @(#)sock.c 1.0.17 06/02/93
9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Florian La Roche, <flla@stud.uni-sb.de>
13 *
14 * Fixes:
15 * Alan Cox : Numerous verify_area() problems
16 * Alan Cox : Connecting on a connecting socket
17 * now returns an error for tcp.
18 * Alan Cox : sock->protocol is set correctly.
19 * and is not sometimes left as 0.
20 * Alan Cox : connect handles icmp errors on a
21 * connect properly. Unfortunately there
22 * is a restart syscall nasty there. I
23 * can't match BSD without hacking the C
24 * library. Ideas urgently sought!
25 * Alan Cox : Disallow bind() to addresses that are
26 * not ours - especially broadcast ones!!
27 * Alan Cox : Socket 1024 _IS_ ok for users. (fencepost)
28 * Alan Cox : sock_wfree/sock_rfree don't destroy sockets,
29 * instead they leave that for the DESTROY timer.
30 * Alan Cox : Clean up error flag in accept
31 * Alan Cox : TCP ack handling is buggy, the DESTROY timer
32 * was buggy. Put a remove_sock() in the handler
33 * for memory when we hit 0. Also altered the timer
34 * code. The ACK stuff can wait and needs major
35 * TCP layer surgery.
36 * Alan Cox : Fixed TCP ack bug, removed remove sock
37 * and fixed timer/inet_bh race.
38 * Alan Cox : Added zapped flag for TCP
39 * Alan Cox : Move kfree_skb into skbuff.c and tidied up surplus code
40 * Alan Cox : for new sk_buff allocations wmalloc/rmalloc now call alloc_skb
41 * Alan Cox : kfree_s calls now are kfree_skbmem so we can track skb resources
42 * Alan Cox : Supports socket option broadcast now as does udp. Packet and raw need fixing.
43 * Alan Cox : Added RCVBUF,SNDBUF size setting. It suddenely occured to me how easy it was so...
44 * Rick Sladkey : Relaxed UDP rules for matching packets.
45 * C.E.Hawkins : IFF_PROMISC/SIOCGHWADDR support
46 * Pauline Middelink : Pidentd support
47 * Alan Cox : Fixed connect() taking signals I think.
48 * Alan Cox : SO_LINGER supported
49 * Alan Cox : Error reporting fixes
50 * Anonymous : inet_create tidied up (sk->reuse setting)
51 * Alan Cox : inet sockets don't set sk->type!
52 * Alan Cox : Split socket option code
53 * Alan Cox : Callbacks
54 * Alan Cox : Nagle flag for Charles & Johannes stuff
55 *
56 * To Fix:
57 *
58 *
59 * This program is free software; you can redistribute it and/or
60 * modify it under the terms of the GNU General Public License
61 * as published by the Free Software Foundation; either version
62 * 2 of the License, or (at your option) any later version.
63 */
64
65 #include <linux/config.h>
66 #include <linux/errno.h>
67 #include <linux/types.h>
68 #include <linux/socket.h>
69 #include <linux/in.h>
70 #include <linux/kernel.h>
71 #include <linux/major.h>
72 #include <linux/sched.h>
73 #include <linux/timer.h>
74 #include <linux/string.h>
75 #include <linux/sockios.h>
76 #include <linux/net.h>
77 #include <linux/fcntl.h>
78 #include <linux/mm.h>
79 #include <linux/interrupt.h>
80
81 #include <asm/segment.h>
82 #include <asm/system.h>
83
84 #include "inet.h"
85 #include "dev.h"
86 #include "ip.h"
87 #include "protocol.h"
88 #include "arp.h"
89 #include "route.h"
90 #include "tcp.h"
91 #include "udp.h"
92 #include "skbuff.h"
93 #include "sock.h"
94 #include "raw.h"
95 #include "icmp.h"
96
97
98 int inet_debug = DBG_OFF; /* INET module debug flag */
99
100
101 #define min(a,b) ((a)<(b)?(a):(b))
102
103 extern struct proto packet_prot;
104
105
106 void
107 print_sk(struct sock *sk)
108 {
109 if (!sk) {
110 printk(" print_sk(NULL)\n");
111 return;
112 }
113 printk(" wmem_alloc = %lu\n", sk->wmem_alloc);
114 printk(" rmem_alloc = %lu\n", sk->rmem_alloc);
115 printk(" send_head = %p\n", sk->send_head);
116 printk(" state = %d\n",sk->state);
117 printk(" wback = %p, rqueue = %p\n", sk->wback, sk->rqueue);
118 printk(" wfront = %p\n", sk->wfront);
119 printk(" daddr = %lX, saddr = %lX\n", sk->daddr,sk->saddr);
120 printk(" num = %d", sk->num);
121 printk(" next = %p\n", sk->next);
122 printk(" write_seq = %ld, acked_seq = %ld, copied_seq = %ld\n",
123 sk->write_seq, sk->acked_seq, sk->copied_seq);
124 printk(" rcv_ack_seq = %ld, window_seq = %ld, fin_seq = %ld\n",
125 sk->rcv_ack_seq, sk->window_seq, sk->fin_seq);
126 printk(" prot = %p\n", sk->prot);
127 printk(" pair = %p, back_log = %p\n", sk->pair,sk->back_log);
128 printk(" inuse = %d , blog = %d\n", sk->inuse, sk->blog);
129 printk(" dead = %d delay_acks=%d\n", sk->dead, sk->delay_acks);
130 printk(" retransmits = %ld, timeout = %d\n", sk->retransmits, sk->timeout);
131 printk(" cong_window = %d, packets_out = %d\n", sk->cong_window,
132 sk->packets_out);
133 printk(" shutdown=%d\n", sk->shutdown);
134 }
135
136
137 void
138 print_skb(struct sk_buff *skb)
139 {
140 if (!skb) {
141 printk(" print_skb(NULL)\n");
142 return;
143 }
144 printk(" prev = %p, next = %p\n", skb->prev, skb->next);
145 printk(" sk = %p link3 = %p\n", skb->sk, skb->link3);
146 printk(" mem_addr = %p, mem_len = %lu\n", skb->mem_addr, skb->mem_len);
147 printk(" used = %d free = %d\n", skb->used,skb->free);
148 }
149
150
151
152 static int
153 sk_inuse(struct proto *prot, int num)
154 {
155 struct sock *sk;
156
157 for(sk = prot->sock_array[num & (SOCK_ARRAY_SIZE -1 )];
158 sk != NULL;
159 sk=sk->next) {
160 if (sk->num == num) return(1);
161 }
162 return(0);
163 }
164
165
166 unsigned short
167 get_new_socknum(struct proto *prot, unsigned short base)
168 {
169 static int start=0;
170
171 /*
172 * Used to cycle through the port numbers so the
173 * chances of a confused connection drop.
174 */
175 int i, j;
176 int best = 0;
177 int size = 32767; /* a big num. */
178 struct sock *sk;
179
180 if (base == 0) base = PROT_SOCK+1+(start % 1024);
181 if (base <= PROT_SOCK) {
182 base += PROT_SOCK+(start % 1024);
183 }
184
185 /* Now look through the entire array and try to find an empty ptr. */
186 for(i=0; i < SOCK_ARRAY_SIZE; i++) {
187 j = 0;
188 sk = prot->sock_array[(i+base+1) &(SOCK_ARRAY_SIZE -1)];
189 while(sk != NULL) {
190 sk = sk->next;
191 j++;
192 }
193 if (j == 0) {
194 start =(i+1+start )%1024;
195 DPRINTF((DBG_INET, "get_new_socknum returning %d, start = %d\n",
196 i + base + 1, start));
197 return(i+base+1);
198 }
199 if (j < size) {
200 best = i;
201 size = j;
202 }
203 }
204
205 /* Now make sure the one we want is not in use. */
206 while(sk_inuse(prot, base +best+1)) {
207 best += SOCK_ARRAY_SIZE;
208 }
209 DPRINTF((DBG_INET, "get_new_socknum returning %d, start = %d\n",
210 best + base + 1, start));
211 return(best+base+1);
212 }
213
214
215 void
216 put_sock(unsigned short num, struct sock *sk)
217 {
218 struct sock *sk1;
219 struct sock *sk2;
220 int mask;
221
222 DPRINTF((DBG_INET, "put_sock(num = %d, sk = %X\n", num, sk));
223 sk->num = num;
224 sk->next = NULL;
225 num = num &(SOCK_ARRAY_SIZE -1);
226
227 /* We can't have an interupt re-enter here. */
228 cli();
229 if (sk->prot->sock_array[num] == NULL) {
230 sk->prot->sock_array[num] = sk;
231 sti();
232 return;
233 }
234 sti();
235 for(mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask) {
236 if ((mask & sk->saddr) &&
237 (mask & sk->saddr) != (mask & 0xffffffff)) {
238 mask = mask << 8;
239 break;
240 }
241 }
242 DPRINTF((DBG_INET, "mask = %X\n", mask));
243
244 cli();
245 sk1 = sk->prot->sock_array[num];
246 for(sk2 = sk1; sk2 != NULL; sk2=sk2->next) {
247 if (!(sk2->saddr & mask)) {
248 if (sk2 == sk1) {
249 sk->next = sk->prot->sock_array[num];
250 sk->prot->sock_array[num] = sk;
251 sti();
252 return;
253 }
254 sk->next = sk2;
255 sk1->next= sk;
256 sti();
257 return;
258 }
259 sk1 = sk2;
260 }
261
262 /* Goes at the end. */
263 sk->next = NULL;
264 sk1->next = sk;
265 sti();
266 }
267
268
269 static void
270 remove_sock(struct sock *sk1)
271 {
272 struct sock *sk2;
273
274 DPRINTF((DBG_INET, "remove_sock(sk1=%X)\n", sk1));
275 if (!sk1) {
276 printk("sock.c: remove_sock: sk1 == NULL\n");
277 return;
278 }
279
280 if (!sk1->prot) {
281 printk("sock.c: remove_sock: sk1->prot == NULL\n");
282 return;
283 }
284
285 /* We can't have this changing out from under us. */
286 cli();
287 sk2 = sk1->prot->sock_array[sk1->num &(SOCK_ARRAY_SIZE -1)];
288 if (sk2 == sk1) {
289 sk1->prot->sock_array[sk1->num &(SOCK_ARRAY_SIZE -1)] = sk1->next;
290 sti();
291 return;
292 }
293
294 while(sk2 && sk2->next != sk1) {
295 sk2 = sk2->next;
296 }
297
298 if (sk2) {
299 sk2->next = sk1->next;
300 sti();
301 return;
302 }
303 sti();
304
305 if (sk1->num != 0) DPRINTF((DBG_INET, "remove_sock: sock not found.\n"));
306 }
307
308
309 void
310 destroy_sock(struct sock *sk)
311 {
312 struct sk_buff *skb;
313
314 DPRINTF((DBG_INET, "destroying socket %X\n", sk));
315 sk->inuse = 1; /* just to be safe. */
316
317 /* Incase it's sleeping somewhere. */
318 if (!sk->dead)
319 sk->write_space(sk);
320
321 remove_sock(sk);
322
323 /* Now we can no longer get new packets. */
324 delete_timer(sk);
325
326
327 while ((skb = tcp_dequeue_partial(sk)) != NULL)
328 {
329 IS_SKB(skb);
330 kfree_skb(skb, FREE_WRITE);
331 }
332
333 /* Cleanup up the write buffer. */
334 for(skb = sk->wfront; skb != NULL; )
335 {
336 struct sk_buff *skb2;
337
338 skb2=(struct sk_buff *)skb->next;
339 if (skb->magic != TCP_WRITE_QUEUE_MAGIC) {
340 printk("sock.c:destroy_sock write queue with bad magic(%X)\n",
341 skb->magic);
342 break;
343 }
344 IS_SKB(skb);
345 kfree_skb(skb, FREE_WRITE);
346 skb = skb2;
347 }
348
349 sk->wfront = NULL;
350 sk->wback = NULL;
351
352 if (sk->rqueue != NULL)
353 {
354 while((skb=skb_dequeue(&sk->rqueue))!=NULL)
355 {
356 /*
357 * This will take care of closing sockets that were
358 * listening and didn't accept everything.
359 */
360 if (skb->sk != NULL && skb->sk != sk)
361 {
362 IS_SKB(skb);
363 skb->sk->dead = 1;
364 skb->sk->prot->close(skb->sk, 0);
365 }
366 IS_SKB(skb);
367 kfree_skb(skb, FREE_READ);
368 }
369 }
370 sk->rqueue = NULL;
371
372 /* Now we need to clean up the send head. */
373 for(skb = sk->send_head; skb != NULL; )
374 {
375 struct sk_buff *skb2;
376
377 /*
378 * We need to remove skb from the transmit queue,
379 * or maybe the arp queue.
380 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -