b5fcaa09cf23a5eb66d09721c66355641da4e76c
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. 6 * Generic socket support routines. Memory allocators, socket lock/release 7 * handler for protocols to use and generic option handler. 10 * Version: @(#)sock.c 1.0.17 06/02/93 12 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 14 * Florian La Roche, <flla@stud.uni-sb.de> 15 * Alan Cox, <A.Cox@swansea.ac.uk> 18 * Alan Cox : Numerous verify_area() problems 19 * Alan Cox : Connecting on a connecting socket 20 * now returns an error for tcp. 21 * Alan Cox : sock->protocol is set correctly. 22 * and is not sometimes left as 0. 23 * Alan Cox : connect handles icmp errors on a 24 * connect properly. Unfortunately there 25 * is a restart syscall nasty there. I 26 * can't match BSD without hacking the C 27 * library. Ideas urgently sought! 28 * Alan Cox : Disallow bind() to addresses that are 29 * not ours - especially broadcast ones!! 30 * Alan Cox : Socket 1024 _IS_ ok for users. (fencepost) 31 * Alan Cox : sock_wfree/sock_rfree don't destroy sockets, 32 * instead they leave that for the DESTROY timer. 33 * Alan Cox : Clean up error flag in accept 34 * Alan Cox : TCP ack handling is buggy, the DESTROY timer 35 * was buggy. Put a remove_sock() in the handler 36 * for memory when we hit 0. Also altered the timer 37 * code. The ACK stuff can wait and needs major 39 * Alan Cox : Fixed TCP ack bug, removed remove sock 40 * and fixed timer/inet_bh race. 41 * Alan Cox : Added zapped flag for TCP 42 * Alan Cox : Move kfree_skb into skbuff.c and tidied up surplus code 43 * Alan Cox : for new sk_buff allocations wmalloc/rmalloc now call alloc_skb 44 * Alan Cox : kfree_s calls now are kfree_skbmem so we can track skb resources 45 * Alan Cox : Supports socket option broadcast now as does udp. Packet and raw need fixing. 46 * Alan Cox : Added RCVBUF,SNDBUF size setting. It suddenly occurred to me how easy it was so... 47 * Rick Sladkey : Relaxed UDP rules for matching packets. 48 * C.E.Hawkins : IFF_PROMISC/SIOCGHWADDR support 49 * Pauline Middelink : identd support 50 * Alan Cox : Fixed connect() taking signals I think. 51 * Alan Cox : SO_LINGER supported 52 * Alan Cox : Error reporting fixes 53 * Anonymous : inet_create tidied up (sk->reuse setting) 54 * Alan Cox : inet sockets don't set sk->type! 55 * Alan Cox : Split socket option code 56 * Alan Cox : Callbacks 57 * Alan Cox : Nagle flag for Charles & Johannes stuff 58 * Alex : Removed restriction on inet fioctl 59 * Alan Cox : Splitting INET from NET core 60 * Alan Cox : Fixed bogus SO_TYPE handling in getsockopt() 61 * Adam Caldwell : Missing return in SO_DONTROUTE/SO_DEBUG code 62 * Alan Cox : Split IP from generic code 63 * Alan Cox : New kfree_skbmem() 64 * Alan Cox : Make SO_DEBUG superuser only. 65 * Alan Cox : Allow anyone to clear SO_DEBUG 67 * Alan Cox : Added optimistic memory grabbing for AF_UNIX throughput. 68 * Alan Cox : Allocator for a socket is settable. 69 * Alan Cox : SO_ERROR includes soft errors. 70 * Alan Cox : Allow NULL arguments on some SO_ opts 71 * Alan Cox : Generic socket allocation to make hooks 72 * easier (suggested by Craig Metz). 73 * Michael Pall : SO_ERROR returns positive errno again 78 * This program is free software; you can redistribute it and/or 79 * modify it under the terms of the GNU General Public License 80 * as published by the Free Software Foundation; either version 81 * 2 of the License, or (at your option) any later version. 84 #include <linux/config.h> 85 #include <linux/errno.h> 86 #include <linux/types.h> 87 #include <linux/socket.h> 89 #include <linux/kernel.h> 90 #include <linux/major.h> 91 #include <linux/sched.h> 92 #include <linux/timer.h> 93 #include <linux/string.h> 94 #include <linux/sockios.h> 95 #include <linux/net.h> 96 #include <linux/fcntl.h> 98 #include <linux/interrupt.h> 100 #include <asm/uaccess.h> 101 #include <asm/system.h> 103 #include <linux/inet.h> 104 #include <linux/netdevice.h> 106 #include <net/protocol.h> 108 #include <net/rarp.h> 109 #include <net/route.h> 112 #include <linux/skbuff.h> 113 #include <net/sock.h> 115 #include <net/icmp.h> 117 #define min(a,b) ((a)<(b)?(a):(b)) 120 * This is meant for all protocols to use and covers goings on 121 * at the socket level. Everything here is generic. 124 intsock_setsockopt(struct sock
*sk
,int level
,int optname
, 125 char*optval
,int optlen
) 133 * Options without arguments 136 #ifdef SO_DONTLINGER/* Compatibility item... */ 148 err
=verify_area(VERIFY_READ
, optval
,sizeof(int)); 152 get_user(val
, (int*)optval
); 167 return(-ENOPROTOOPT
); 169 sk
->localroute
=valbool
; 172 sk
->broadcast
=valbool
; 175 if(val
> SK_WMEM_MAX
*2) 185 if(val
> SK_RMEM_MAX
*2) 195 if(sk
->protocol
== IPPROTO_TCP
) 197 tcp_set_keepalive(sk
, valbool
); 199 sk
->keepopen
= valbool
; 203 sk
->urginline
= valbool
; 207 sk
->no_check
= valbool
; 211 if(val
>=0&& val
< DEV_NUMBUFFS
) 223 err
=verify_area(VERIFY_READ
,optval
,sizeof(ling
)); 226 copy_from_user(&ling
,optval
,sizeof(ling
)); 231 sk
->lingertime
=ling
.l_linger
; 237 sk
->bsdism
= valbool
; 241 return(-ENOPROTOOPT
); 246 intsock_getsockopt(struct sock
*sk
,int level
,int optname
, 247 char*optval
,int*optlen
) 260 val
= sk
->localroute
; 288 val
= -sock_error(sk
); 290 val
=xchg(&sk
->err_soft
,0); 306 err
=verify_area(VERIFY_WRITE
,optval
,sizeof(ling
)); 309 err
=verify_area(VERIFY_WRITE
,optlen
,sizeof(int)); 312 put_user(sizeof(ling
), optlen
); 313 ling
.l_onoff
=sk
->linger
; 314 ling
.l_linger
=sk
->lingertime
; 315 copy_to_user(optval
,&ling
,sizeof(ling
)); 323 return(-ENOPROTOOPT
); 325 err
=verify_area(VERIFY_WRITE
, optlen
,sizeof(int)); 328 put_user(sizeof(int), optlen
); 330 err
=verify_area(VERIFY_WRITE
, optval
,sizeof(int)); 333 put_user(val
,(unsigned int*)optval
); 338 struct sock
*sk_alloc(int priority
) 340 struct sock
*sk
=(struct sock
*)kmalloc(sizeof(*sk
), priority
); 343 memset(sk
,0,sizeof(*sk
)); 347 voidsk_free(struct sock
*sk
) 349 kfree_s(sk
,sizeof(*sk
)); 353 struct sk_buff
*sock_wmalloc(struct sock
*sk
,unsigned long size
,int force
,int priority
) 356 if(force
|| sk
->wmem_alloc
< sk
->sndbuf
) { 357 struct sk_buff
* skb
=alloc_skb(size
, priority
); 359 atomic_add(skb
->truesize
, &sk
->wmem_alloc
); 364 returnalloc_skb(size
, priority
); 367 struct sk_buff
*sock_rmalloc(struct sock
*sk
,unsigned long size
,int force
,int priority
) 370 if(force
|| sk
->rmem_alloc
< sk
->rcvbuf
) { 371 struct sk_buff
*skb
=alloc_skb(size
, priority
); 373 atomic_add(skb
->truesize
, &sk
->rmem_alloc
); 378 returnalloc_skb(size
, priority
); 382 unsigned longsock_rspace(struct sock
*sk
) 388 if(sk
->rmem_alloc
>= sk
->rcvbuf
-2*MIN_WINDOW
) 390 amt
=min((sk
->rcvbuf
-sk
->rmem_alloc
)/2-MIN_WINDOW
, MAX_WINDOW
); 399 unsigned longsock_wspace(struct sock
*sk
) 403 if(sk
->shutdown
& SEND_SHUTDOWN
) 405 if(sk
->wmem_alloc
>= sk
->sndbuf
) 407 return sk
->sndbuf
- sk
->wmem_alloc
; 413 voidsock_wfree(struct sock
*sk
,struct sk_buff
*skb
) 422 /* In case it might be waiting for more memory. */ 424 atomic_sub(s
, &sk
->wmem_alloc
); 429 voidsock_rfree(struct sock
*sk
,struct sk_buff
*skb
) 438 atomic_sub(s
, &sk
->rmem_alloc
); 443 * Generic send/receive buffer handlers 446 struct sk_buff
*sock_alloc_send_skb(struct sock
*sk
,unsigned long size
,unsigned long fallback
,int noblock
,int*errcode
) 463 if(sk
->shutdown
&SEND_SHUTDOWN
) 470 skb
=sock_wmalloc(sk
, size
,0, sk
->allocation
); 473 /* The buffer get won't block, or use the atomic queue. It does 474 produce annoying no free page messages still.... */ 475 skb
=sock_wmalloc(sk
, size
,0, GFP_BUFFER
); 477 skb
=sock_wmalloc(sk
, fallback
,0, GFP_KERNEL
); 481 * This means we have too many buffers for this socket already. 488 sk
->socket
->flags
|= SO_NOSPACE
; 494 if(sk
->shutdown
&SEND_SHUTDOWN
) 499 tmp
= sk
->wmem_alloc
; 501 if(sk
->shutdown
&SEND_SHUTDOWN
) 509 if( tmp
<= sk
->wmem_alloc
) 511 /* ANK: Line above seems either incorrect 512 * or useless. sk->wmem_alloc has a tiny chance to change 513 * between tmp = sk->w... and cli(), 514 * but it might(?) change earlier. In real life 515 * it does not (I never seen the message). 516 * In any case I'd delete this check at all, or 519 if(sk
->wmem_alloc
+ size
>= sk
->sndbuf
) 522 sk
->socket
->flags
&= ~SO_NOSPACE
; 523 interruptible_sleep_on(sk
->sleep
); 524 if(current
->signal
& ~current
->blocked
) 527 *errcode
= -ERESTARTSYS
; 540 void__release_sock(struct sock
*sk
) 543 if(!sk
->prot
|| !sk
->backlog_rcv
) 546 /* See if we have any packets built up. */ 548 while(!skb_queue_empty(&sk
->back_log
)) { 549 struct sk_buff
* skb
= sk
->back_log
.next
; 550 __skb_unlink(skb
, &sk
->back_log
); 551 sk
->backlog_rcv(sk
, skb
);