This source file includes following definitions.
- sock_setsockopt
- sock_getsockopt
- sock_wmalloc
- sock_rmalloc
- sock_rspace
- sock_wspace
- sock_wfree
- sock_rfree
- sock_alloc_send_skb
- release_sock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 #include <linux/config.h>
80 #include <linux/errno.h>
81 #include <linux/types.h>
82 #include <linux/socket.h>
83 #include <linux/in.h>
84 #include <linux/kernel.h>
85 #include <linux/major.h>
86 #include <linux/sched.h>
87 #include <linux/timer.h>
88 #include <linux/string.h>
89 #include <linux/sockios.h>
90 #include <linux/net.h>
91 #include <linux/fcntl.h>
92 #include <linux/mm.h>
93 #include <linux/interrupt.h>
94
95 #include <asm/segment.h>
96 #include <asm/system.h>
97
98 #include <linux/inet.h>
99 #include <linux/netdevice.h>
100 #include <net/ip.h>
101 #include <net/protocol.h>
102 #include <net/arp.h>
103 #include <net/rarp.h>
104 #include <net/route.h>
105 #include <net/tcp.h>
106 #include <net/udp.h>
107 #include <linux/skbuff.h>
108 #include <net/sock.h>
109 #include <net/raw.h>
110 #include <net/icmp.h>
111
112 #define min(a,b) ((a)<(b)?(a):(b))
113
114
115
116
117
118
119 int sock_setsockopt(struct sock *sk, int level, int optname,
120 char *optval, int optlen)
121 {
122 int val;
123 int valbool;
124 int err;
125 struct linger ling;
126
127 if (optval == NULL)
128 return(-EINVAL);
129
130 err=verify_area(VERIFY_READ, optval, sizeof(int));
131 if(err)
132 return err;
133
134 val = get_user((int *)optval);
135 valbool = val?1:0;
136
137 switch(optname)
138 {
139 case SO_DEBUG:
140 if(val && !suser())
141 return(-EPERM);
142 sk->debug=valbool;
143 return 0;
144 case SO_REUSEADDR:
145 sk->reuse = valbool;
146 return(0);
147 case SO_TYPE:
148 case SO_ERROR:
149 return(-ENOPROTOOPT);
150 case SO_DONTROUTE:
151 sk->localroute=valbool;
152 return 0;
153 case SO_BROADCAST:
154 sk->broadcast=valbool;
155 return 0;
156 case SO_SNDBUF:
157 if(val>32767)
158 val=32767;
159 if(val<256)
160 val=256;
161 sk->sndbuf=val;
162 return 0;
163
164 case SO_RCVBUF:
165 if(val>32767)
166 val=32767;
167 if(val<256)
168 val=256;
169 sk->rcvbuf=val;
170 return(0);
171
172 case SO_KEEPALIVE:
173 sk->keepopen = valbool;
174 return(0);
175
176 case SO_OOBINLINE:
177 sk->urginline = valbool;
178 return(0);
179
180 case SO_NO_CHECK:
181 sk->no_check = valbool;
182 return(0);
183
184 case SO_PRIORITY:
185 if (val >= 0 && val < DEV_NUMBUFFS)
186 {
187 sk->priority = val;
188 }
189 else
190 {
191 return(-EINVAL);
192 }
193 return(0);
194
195
196 case SO_LINGER:
197 err=verify_area(VERIFY_READ,optval,sizeof(ling));
198 if(err)
199 return err;
200 memcpy_fromfs(&ling,optval,sizeof(ling));
201 if(ling.l_onoff==0)
202 sk->linger=0;
203 else
204 {
205 sk->lingertime=ling.l_linger;
206 sk->linger=1;
207 }
208 return 0;
209
210 case SO_BSDCOMPAT:
211 sk->bsdism = valbool;
212 return 0;
213
214 default:
215 return(-ENOPROTOOPT);
216 }
217 }
218
219
220 int sock_getsockopt(struct sock *sk, int level, int optname,
221 char *optval, int *optlen)
222 {
223 int val;
224 int err;
225 struct linger ling;
226
227 switch(optname)
228 {
229 case SO_DEBUG:
230 val = sk->debug;
231 break;
232
233 case SO_DONTROUTE:
234 val = sk->localroute;
235 break;
236
237 case SO_BROADCAST:
238 val= sk->broadcast;
239 break;
240
241 case SO_SNDBUF:
242 val=sk->sndbuf;
243 break;
244
245 case SO_RCVBUF:
246 val =sk->rcvbuf;
247 break;
248
249 case SO_REUSEADDR:
250 val = sk->reuse;
251 break;
252
253 case SO_KEEPALIVE:
254 val = sk->keepopen;
255 break;
256
257 case SO_TYPE:
258 val = sk->type;
259 break;
260
261 case SO_ERROR:
262 val = sk->err;
263 sk->err = 0;
264 break;
265
266 case SO_OOBINLINE:
267 val = sk->urginline;
268 break;
269
270 case SO_NO_CHECK:
271 val = sk->no_check;
272 break;
273
274 case SO_PRIORITY:
275 val = sk->priority;
276 break;
277
278 case SO_LINGER:
279 err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
280 if(err)
281 return err;
282 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
283 if(err)
284 return err;
285 put_fs_long(sizeof(ling),(unsigned long *)optlen);
286 ling.l_onoff=sk->linger;
287 ling.l_linger=sk->lingertime;
288 memcpy_tofs(optval,&ling,sizeof(ling));
289 return 0;
290
291 case SO_BSDCOMPAT:
292 val = sk->bsdism;
293 break;
294
295 default:
296 return(-ENOPROTOOPT);
297 }
298 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
299 if(err)
300 return err;
301 put_fs_long(sizeof(int),(unsigned long *) optlen);
302
303 err=verify_area(VERIFY_WRITE, optval, sizeof(int));
304 if(err)
305 return err;
306 put_fs_long(val,(unsigned long *)optval);
307
308 return(0);
309 }
310
311
312 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority)
313 {
314 if (sk)
315 {
316 if (sk->wmem_alloc + size < sk->sndbuf || force)
317 {
318 struct sk_buff * c = alloc_skb(size, priority);
319 if (c)
320 {
321 unsigned long flags;
322 save_flags(flags);
323 cli();
324 sk->wmem_alloc+= c->truesize;
325 restore_flags(flags);
326 }
327 return c;
328 }
329 return(NULL);
330 }
331 return(alloc_skb(size, priority));
332 }
333
334
335 struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
336 {
337 if (sk)
338 {
339 if (sk->rmem_alloc + size < sk->rcvbuf || force)
340 {
341 struct sk_buff *c = alloc_skb(size, priority);
342 if (c)
343 {
344 unsigned long flags;
345 save_flags(flags);
346 cli();
347 sk->rmem_alloc += c->truesize;
348 restore_flags(flags);
349 }
350 return(c);
351 }
352 return(NULL);
353 }
354 return(alloc_skb(size, priority));
355 }
356
357
358 unsigned long sock_rspace(struct sock *sk)
359 {
360 int amt;
361
362 if (sk != NULL)
363 {
364 if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW)
365 return(0);
366 amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
367 if (amt < 0)
368 return(0);
369 return(amt);
370 }
371 return(0);
372 }
373
374
375 unsigned long sock_wspace(struct sock *sk)
376 {
377 if (sk != NULL)
378 {
379 if (sk->shutdown & SEND_SHUTDOWN)
380 return(0);
381 if (sk->wmem_alloc >= sk->sndbuf)
382 return(0);
383 return(sk->sndbuf-sk->wmem_alloc );
384 }
385 return(0);
386 }
387
388
389 void sock_wfree(struct sock *sk, struct sk_buff *skb)
390 {
391 int s=skb->truesize;
392 #if CONFIG_SKB_CHECK
393 IS_SKB(skb);
394 #endif
395 kfree_skbmem(skb);
396 if (sk)
397 {
398 unsigned long flags;
399 save_flags(flags);
400 cli();
401 sk->wmem_alloc -= s;
402 restore_flags(flags);
403
404 sk->write_space(sk);
405 return;
406 }
407 }
408
409
410 void sock_rfree(struct sock *sk, struct sk_buff *skb)
411 {
412 int s=skb->truesize;
413 #if CONFIG_SKB_CHECK
414 IS_SKB(skb);
415 #endif
416 kfree_skbmem(skb);
417 if (sk)
418 {
419 unsigned long flags;
420 save_flags(flags);
421 cli();
422 sk->rmem_alloc -= s;
423 restore_flags(flags);
424 }
425 }
426
427
428
429
430
431 struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigned long fallback, int noblock, int *errcode)
432 {
433 struct sk_buff *skb;
434 int err;
435
436 sk->inuse=1;
437
438 do
439 {
440 if(sk->err!=0)
441 {
442 cli();
443 err= -sk->err;
444 sk->err=0;
445 sti();
446 *errcode=err;
447 return NULL;
448 }
449
450 if(sk->shutdown&SEND_SHUTDOWN)
451 {
452 *errcode=-EPIPE;
453 return NULL;
454 }
455
456 if(!fallback)
457 skb = sock_wmalloc(sk, size, 0, sk->allocation);
458 else
459 {
460
461
462 skb = sock_wmalloc(sk, size, 0 , GFP_BUFFER);
463 if(!skb)
464 skb=sock_wmalloc(sk, fallback, 0, GFP_KERNEL);
465 }
466
467
468
469
470
471 if(skb==NULL)
472 {
473 unsigned long tmp;
474
475 sk->socket->flags |= SO_NOSPACE;
476 if(noblock)
477 {
478 *errcode=-EAGAIN;
479 return NULL;
480 }
481 if(sk->shutdown&SEND_SHUTDOWN)
482 {
483 *errcode=-EPIPE;
484 return NULL;
485 }
486 tmp = sk->wmem_alloc;
487 cli();
488 if(sk->shutdown&SEND_SHUTDOWN)
489 {
490 sti();
491 *errcode=-EPIPE;
492 return NULL;
493 }
494
495 #if 1
496 if( tmp <= sk->wmem_alloc)
497 #else
498
499
500
501
502
503
504
505
506 if (sk->wmem_alloc + size >= sk->sndbuf)
507 #endif
508 {
509 if (sk->wmem_alloc <= 0)
510 printk("sock.c: Look where I am %ld<%ld\n", tmp, sk->wmem_alloc);
511 sk->socket->flags &= ~SO_NOSPACE;
512 interruptible_sleep_on(sk->sleep);
513 if (current->signal & ~current->blocked)
514 {
515 sti();
516 *errcode = -ERESTARTSYS;
517 return NULL;
518 }
519 }
520 sti();
521 }
522 }
523 while(skb==NULL);
524
525 return skb;
526 }
527
528
529 void release_sock(struct sock *sk)
530 {
531 unsigned long flags;
532 #ifdef CONFIG_INET
533 struct sk_buff *skb;
534 #endif
535
536 if (!sk->prot)
537 return;
538
539
540
541
542
543
544
545 save_flags(flags);
546 cli();
547 if (sk->blog)
548 {
549 restore_flags(flags);
550 return;
551 }
552 sk->blog=1;
553 sk->inuse = 1;
554 restore_flags(flags);
555 #ifdef CONFIG_INET
556
557 while((skb = skb_dequeue(&sk->back_log)) != NULL)
558 {
559 sk->blog = 1;
560 if (sk->prot->rcv)
561 sk->prot->rcv(skb, skb->dev, (struct options*)skb->proto_priv,
562 skb->saddr, skb->len, skb->daddr, 1,
563
564 (struct inet_protocol *)sk->pair);
565 }
566 #endif
567 sk->blog = 0;
568 sk->inuse = 0;
569 #ifdef CONFIG_INET
570 if (sk->dead && sk->state == TCP_CLOSE)
571 {
572
573 reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
574 }
575 #endif
576 }