|
|
1.1 root 1: #include <signal.h>
2: #include <errno.h>
3: #include <linux/sched.h>
4: #include <linux/kernel.h>
5: #include <asm/system.h>
6: #include <asm/segment.h>
7: #include <sys/socket.h>
8: #include <sys/stat.h>
9: #include <fcntl.h>
10: #include <termios.h>
11: #include "kern_sock.h"
12: #include "socketcall.h"
13:
14: extern int sys_close(int fd);
15:
16: extern struct proto_ops unix_proto_ops;
17:
18: static struct {
19: short family;
20: char *name;
21: struct proto_ops *ops;
22: } proto_table[] = {
23: AF_UNIX, "AF_UNIX", &unix_proto_ops
24: };
25: #define NPROTO (sizeof(proto_table) / sizeof(proto_table[0]))
26:
27: static char *
28: family_name(int family)
29: {
30: int i;
31:
32: for (i = 0; i < NPROTO; ++i)
33: if (proto_table[i].family == family)
34: return proto_table[i].name;
35: return "UNKNOWN";
36: }
37:
38: static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
39: int whence);
40: static int sock_read(struct inode *inode, struct file *file, char *buf,
41: int size);
42: static int sock_write(struct inode *inode, struct file *file, char *buf,
43: int size);
44: static int sock_readdir(struct inode *inode, struct file *file,
45: struct dirent *dirent, int count);
46: static void sock_close(struct inode *inode, struct file *file);
47: /*static*/ int sock_select(struct inode *inode, struct file *file, int which,
48: select_table *seltable);
49: static int sock_ioctl(struct inode *inode, struct file *file,
50: unsigned int cmd, unsigned int arg);
51:
52: static struct file_operations socket_file_ops = {
53: sock_lseek,
54: sock_read,
55: sock_write,
56: sock_readdir,
57: sock_select, /* not in vfs yet */
58: sock_ioctl,
59: NULL, /* no special open code... */
60: sock_close
61: };
62:
63: #define SOCK_INODE(S) ((struct inode *)(S)->dummy)
64:
65: static struct socket sockets[NSOCKETS];
66: #define last_socket (sockets + NSOCKETS - 1)
67: static struct task_struct *socket_wait_free = NULL;
68:
69: /*
70: * obtains the first available file descriptor and sets it up for use
71: */
72: static int
73: get_fd(struct inode *inode)
74: {
75: int fd, i;
76: struct file *file;
77:
78: /*
79: * find a file descriptor suitable for return to the user.
80: */
81: for (fd = 0; fd < NR_OPEN; ++fd)
82: if (!current->filp[fd])
83: break;
84: if (fd == NR_OPEN)
85: return -1;
86: current->close_on_exec &= ~(1 << fd);
87: for (file = file_table, i = 0; i < NR_FILE; ++i, ++file)
88: if (!file->f_count)
89: break;
90: if (i == NR_FILE)
91: return -1;
92: current->filp[fd] = file;
93: file->f_op = &socket_file_ops;
94: file->f_mode = 3;
95: file->f_flags = 0;
96: file->f_count = 1;
97: file->f_inode = inode;
98: file->f_pos = 0;
99: return fd;
100: }
101:
102: /*
103: * reverses the action of get_fd() by releasing the file. it closes the
104: * descriptor, but makes sure it does nothing more. called when an incomplete
105: * socket must be closed, along with sock_release().
106: */
107: static inline void
108: toss_fd(int fd)
109: {
110: current->filp[fd]->f_inode = NULL; /* safe from iput */
111: sys_close(fd);
112: }
113:
114: static inline struct socket *
115: socki_lookup(struct inode *inode)
116: {
117: struct socket *sock;
118:
119: for (sock = sockets; sock <= last_socket; ++sock)
120: if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
121: return sock;
122: return NULL;
123: }
124:
125: static inline struct socket *
126: sockfd_lookup(int fd, struct file **pfile)
127: {
128: struct file *file;
129:
130: if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd]))
131: return NULL;
132: if (pfile)
133: *pfile = file;
134: return socki_lookup(file->f_inode);
135: }
136:
137: static struct socket *
138: sock_alloc(int wait)
139: {
140: struct socket *sock;
141:
142: while (1) {
143: cli();
144: for (sock = sockets; sock <= last_socket; ++sock)
145: if (sock->state == SS_FREE) {
146: sock->state = SS_UNCONNECTED;
147: sti();
148: sock->flags = 0;
149: sock->ops = NULL;
150: sock->data = NULL;
151: sock->conn = NULL;
152: sock->iconn = NULL;
153: /*
154: * this really shouldn't be necessary, but
155: * everything else depends on inodes, so we
156: * grab it.
157: * sleeps are also done on the i_wait member
158: * of this inode.
159: * the close system call will iput this inode
160: * for us.
161: */
162: if (!(SOCK_INODE(sock) = get_empty_inode())) {
163: printk("sock_alloc: no more inodes\n");
164: sock->state = SS_FREE;
165: return NULL;
166: }
167: SOCK_INODE(sock)->i_mode = S_IFSOCK;
168: sock->wait = &SOCK_INODE(sock)->i_wait;
169: PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
170: sock, SOCK_INODE(sock));
171: return sock;
172: }
173: sti();
174: if (!wait)
175: return NULL;
176: PRINTK("sock_alloc: no free sockets, sleeping...\n");
177: interruptible_sleep_on(&socket_wait_free);
178: if (current->signal & ~current->blocked) {
179: PRINTK("sock_alloc: sleep was interrupted\n");
180: return NULL;
181: }
182: PRINTK("sock_alloc: wakeup... trying again...\n");
183: }
184: }
185:
186: static inline void
187: sock_release_peer(struct socket *peer)
188: {
189: peer->state = SS_DISCONNECTING;
190: wake_up(peer->wait);
191: }
192:
193: static void
194: sock_release(struct socket *sock)
195: {
196: int oldstate;
197: struct socket *peersock, *nextsock;
198:
199: PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock,
200: SOCK_INODE(sock));
201: if ((oldstate = sock->state) != SS_UNCONNECTED)
202: sock->state = SS_DISCONNECTING;
203: /*
204: * wake up anyone waiting for connections
205: */
206: for (peersock = sock->iconn; peersock; peersock = nextsock) {
207: nextsock = peersock->next;
208: sock_release_peer(peersock);
209: }
210: /*
211: * wake up anyone we're connected to. first, we release the
212: * protocol, to give it a chance to flush data, etc.
213: */
214: peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
215: if (sock->ops)
216: sock->ops->release(sock, peersock);
217: if (peersock)
218: sock_release_peer(peersock);
219: sock->state = SS_FREE; /* this really releases us */
220: wake_up(&socket_wait_free);
221: }
222:
223: static int
224: sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
225: {
226: PRINTK("sock_lseek: huh?\n");
227: return -EBADF;
228: }
229:
230: static int
231: sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
232: {
233: struct socket *sock;
234:
235: PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size);
236: if (!(sock = socki_lookup(inode))) {
237: printk("sock_read: can't find socket for inode!\n");
238: return -EBADF;
239: }
240: if (sock->flags & SO_ACCEPTCON)
241: return -EINVAL;
242: return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK));
243: }
244:
245: static int
246: sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
247: {
248: struct socket *sock;
249:
250: PRINTK("sock_write: buf=0x%x, size=%d\n", ubuf, size);
251: if (!(sock = socki_lookup(inode))) {
252: printk("sock_write: can't find socket for inode!\n");
253: return -EBADF;
254: }
255: if (sock->flags & SO_ACCEPTCON)
256: return -EINVAL;
257: return sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK));
258: }
259:
260: static int
261: sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
262: int count)
263: {
264: PRINTK("sock_readdir: huh?\n");
265: return -EBADF;
266: }
267:
268: int
269: sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
270: unsigned int arg)
271: {
272: struct socket *sock;
273:
274: PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg);
275: if (!(sock = socki_lookup(inode))) {
276: printk("sock_ioctl: can't find socket for inode!\n");
277: return -EBADF;
278: }
279: switch (cmd) {
280: case TIOCINQ:
281: case TIOCOUTQ:
282: if (sock->flags & SO_ACCEPTCON)
283: return -EINVAL;
284: break;
285:
286: default:
287: return -EINVAL;
288: }
289: return sock->ops->ioctl(sock, cmd, arg);
290: }
291:
292: /*static*/ int
293: sock_select(struct inode *inode, struct file *file, int which,
294: select_table *seltable)
295: {
296: struct socket *sock;
297:
298: PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode,
299: (which == SEL_IN) ? "in" :
300: (which == SEL_OUT) ? "out" : "ex");
301: if (!(sock = socki_lookup(inode))) {
302: printk("sock_write: can't find socket for inode!\n");
303: return -EBADF;
304: }
305:
306: /*
307: * handle server sockets specially
308: */
309: if (sock->flags & SO_ACCEPTCON) {
310: if (which == SEL_IN) {
311: PRINTK("sock_select: %sconnections pending\n",
312: sock->iconn ? "" : "no ");
313: return sock->iconn ? 1 : 0;
314: }
315: PRINTK("sock_select: nothing else for server socket\n");
316: return 0;
317: }
318:
319: /*
320: * we can't return errors to select, so its either yes or no.
321: */
322: return sock->ops->select(sock, which) ? 1 : 0;
323: }
324:
325: void
326: sock_close(struct inode *inode, struct file *file)
327: {
328: struct socket *sock;
329:
330: PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count);
331: /*
332: * it's possible the inode is NULL if we're closing an unfinished
333: * socket.
334: */
335: if (!inode)
336: return;
337: if (!(sock = socki_lookup(inode))) {
338: printk("sock_close: can't find socket for inode!\n");
339: return;
340: }
341: sock_release(sock);
342: }
343:
344: int
345: sock_awaitconn(struct socket *mysock, struct socket *servsock)
346: {
347: struct socket *last;
348:
349: PRINTK("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
350: mysock, servsock);
351: if (!(servsock->flags & SO_ACCEPTCON)) {
352: PRINTK("sock_awaitconn: server not accepting connections\n");
353: return -EINVAL;
354: }
355:
356: /*
357: * put ourselves on the server's incomplete connection queue.
358: */
359: mysock->next = NULL;
360: cli();
361: if (!(last = servsock->iconn))
362: servsock->iconn = mysock;
363: else {
364: while (last->next)
365: last = last->next;
366: last->next = mysock;
367: }
368: mysock->state = SS_CONNECTING;
369: mysock->conn = servsock;
370: sti();
371:
372: /*
373: * wake up server, then await connection. server will set state to
374: * SS_CONNECTED if we're connected.
375: */
376: wake_up(servsock->wait);
377: if (mysock->state != SS_CONNECTED) {
378: interruptible_sleep_on(mysock->wait);
379: if (mysock->state != SS_CONNECTED) {
380: /*
381: * if we're not connected we could have been
382: * 1) interrupted, so we need to remove ourselves
383: * from the server list
384: * 2) rejected (mysock->conn == NULL), and have
385: * already been removed from the list
386: */
387: if (mysock->conn == servsock) {
388: cli();
389: if ((last = servsock->iconn) == mysock)
390: servsock->iconn = mysock->next;
391: else {
392: while (last->next != mysock)
393: last = last->next;
394: last->next = mysock->next;
395: }
396: sti();
397: }
398: return mysock->conn ? -EINTR : -EACCES;
399: }
400: }
401: return 0;
402: }
403:
404: /*
405: * perform the socket system call. we locate the appropriate family, then
406: * create a fresh socket.
407: */
408: static int
409: sock_socket(int family, int type, int protocol)
410: {
411: int i, fd;
412: struct socket *sock;
413: struct proto_ops *ops;
414:
415: PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
416: family, family_name(family), type, protocol);
417:
418: /*
419: * locate the correct protocol family
420: */
421: for (i = 0; i < NPROTO; ++i)
422: if (proto_table[i].family == family)
423: break;
424: if (i == NPROTO) {
425: PRINTK("sys_socket: family not found\n");
426: return -EINVAL;
427: }
428: ops = proto_table[i].ops;
429:
430: /*
431: * check that this is a type that we know how to manipulate and
432: * the protocol makes sense here. the family can still reject the
433: * protocol later.
434: */
435: if ((type != SOCK_STREAM &&
436: type != SOCK_DGRAM &&
437: type != SOCK_SEQPACKET &&
438: type != SOCK_RAW) ||
439: protocol < 0)
440: return -EINVAL;
441:
442: /*
443: * allocate the socket and allow the family to set things up. if
444: * the protocol is 0, the family is instructed to select an appropriate
445: * default.
446: */
447: if (!(sock = sock_alloc(1))) {
448: printk("sys_socket: no more sockets\n");
449: return -EAGAIN;
450: }
451: sock->type = type;
452: sock->ops = ops;
453: if ((i = sock->ops->create(sock, protocol)) < 0) {
454: sock_release(sock);
455: return i;
456: }
457:
458: if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
459: sock_release(sock);
460: return -EINVAL;
461: }
462:
463: return fd;
464: }
465:
466: static int
467: sock_socketpair(int family, int type, int protocol, int usockvec[2])
468: {
469: int fd1, fd2, i;
470: struct socket *sock1, *sock2;
471:
472: PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n",
473: family, type, protocol);
474:
475: /*
476: * obtain the first socket and check if the underlying protocol
477: * supports the socketpair call
478: */
479: if ((fd1 = sock_socket(family, type, protocol)) < 0)
480: return fd1;
481: sock1 = sockfd_lookup(fd1, NULL);
482: if (!sock1->ops->socketpair) {
483: sys_close(fd1);
484: return -EINVAL;
485: }
486:
487: /*
488: * now grab another socket and try to connect the two together
489: */
490: if ((fd2 = sock_socket(family, type, protocol)) < 0) {
491: sys_close(fd1);
492: return -EINVAL;
493: }
494: sock2 = sockfd_lookup(fd2, NULL);
495: if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
496: sys_close(fd1);
497: sys_close(fd2);
498: return i;
499: }
500: sock1->conn = sock2;
501: sock2->conn = sock1;
502: sock1->state = SS_CONNECTED;
503: sock2->state = SS_CONNECTED;
504:
505: verify_area(usockvec, 2 * sizeof(int));
506: put_fs_long(fd1, &usockvec[0]);
507: put_fs_long(fd2, &usockvec[1]);
508:
509: return 0;
510: }
511:
512: /*
513: * binds a name to a socket. nothing much to do here since its the
514: * protocol's responsibility to handle the local address
515: */
516: static int
517: sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
518: {
519: struct socket *sock;
520: int i;
521:
522: PRINTK("sys_bind: fd = %d\n", fd);
523: if (!(sock = sockfd_lookup(fd, NULL)))
524: return -EBADF;
525: if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
526: PRINTK("sys_bind: bind failed\n");
527: return i;
528: }
529: return 0;
530: }
531:
532: /*
533: * perform a listen. basically, we allow the protocol to do anything
534: * necessary for a listen, and if that works, we mark the socket as
535: * ready for listening.
536: */
537: static int
538: sock_listen(int fd, int backlog)
539: {
540: struct socket *sock;
541:
542: PRINTK("sys_listen: fd = %d\n", fd);
543: if (!(sock = sockfd_lookup(fd, NULL)))
544: return -EBADF;
545: if (sock->state != SS_UNCONNECTED) {
546: PRINTK("sys_listen: socket isn't unconnected\n");
547: return -EINVAL;
548: }
549: if (sock->flags & SO_ACCEPTCON) {
550: PRINTK("sys_listen: socket already accepting connections!\n");
551: return -EINVAL;
552: }
553: sock->flags |= SO_ACCEPTCON;
554: return 0;
555: }
556:
557: /*
558: * for accept, we attempt to create a new socket, set up the link with the
559: * client, wake up the client, then return the new connected fd.
560: */
561: static int
562: sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
563: {
564: struct file *file;
565: struct socket *sock, *clientsock, *newsock;
566: int i;
567:
568: PRINTK("sys_accept: fd = %d\n", fd);
569: if (!(sock = sockfd_lookup(fd, &file)))
570: return -EBADF;
571: if (sock->state != SS_UNCONNECTED) {
572: PRINTK("sys_accept: socket isn't unconnected\n");
573: return -EINVAL;
574: }
575: if (!(sock->flags & SO_ACCEPTCON)) {
576: PRINTK("sys_accept: socket not accepting connections!\n");
577: return -EINVAL;
578: }
579:
580: /*
581: * if there aren't any sockets awaiting connection, then wait for
582: * one, unless nonblocking
583: */
584: while (!(clientsock = sock->iconn)) {
585: if (file->f_flags & O_NONBLOCK)
586: return -EAGAIN;
587: interruptible_sleep_on(sock->wait);
588: if (current->signal & ~current->blocked) {
589: PRINTK("sys_accept: sleep was interrupted\n");
590: return -EINTR;
591: }
592: }
593:
594: if (!(newsock = sock_alloc(0))) {
595: printk("sys_accept: no more sockets\n");
596: return -EINVAL;
597: }
598: newsock->type = sock->type;
599: newsock->ops = sock->ops;
600: if ((i = sock->ops->dup(newsock, sock)) < 0) {
601: sock_release(newsock);
602: return i;
603: }
604:
605: if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
606: sock_release(newsock);
607: return -EINVAL;
608: }
609:
610: /*
611: * great. finish the connection relative to server and client,
612: * wake up the client and return the new fd to the server
613: */
614: sock->iconn = clientsock->next;
615: clientsock->next = NULL;
616: newsock->conn = clientsock;
617: clientsock->conn = newsock;
618: clientsock->state = SS_CONNECTED;
619: newsock->state = SS_CONNECTED;
620: newsock->ops->accept(sock, newsock);
621: PRINTK("sys_accept: connected socket 0x%x via 0x%x to 0x%x\n",
622: sock, newsock, clientsock);
623: if (upeer_sockaddr)
624: newsock->ops->getname(newsock, upeer_sockaddr,
625: upeer_addrlen, 1);
626: wake_up(clientsock->wait);
627:
628: return fd;
629: }
630:
631: /*
632: * attempt to connect to a socket with the server address.
633: */
634: static int
635: sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
636: {
637: struct socket *sock;
638: int i;
639:
640: PRINTK("sys_connect: fd = %d\n", fd);
641: if (!(sock = sockfd_lookup(fd, NULL)))
642: return -EBADF;
643: if (sock->state != SS_UNCONNECTED) {
644: PRINTK("sys_connect: socket not unconnected\n");
645: return -EINVAL;
646: }
647: if ((i = sock->ops->connect(sock, uservaddr, addrlen)) < 0) {
648: PRINTK("sys_connect: connect failed\n");
649: return i;
650: }
651: return 0;
652: }
653:
654: static int
655: sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
656: {
657: struct socket *sock;
658:
659: PRINTK("sys_getsockname: fd = %d\n", fd);
660: if (!(sock = sockfd_lookup(fd, NULL)))
661: return -EBADF;
662: return sock->ops->getname(sock, usockaddr, usockaddr_len, 0);
663: }
664:
665: static int
666: sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
667: {
668: struct socket *sock;
669:
670: PRINTK("sys_getpeername: fd = %d\n", fd);
671: if (!(sock = sockfd_lookup(fd, NULL)))
672: return -EBADF;
673: return sock->ops->getname(sock, usockaddr, usockaddr_len, 1);
674: }
675:
676: /*
677: * system call vectors. since i want to rewrite sockets as streams, we have
678: * this level of indirection. not a lot of overhead, since more of the work is
679: * done via read/write/select directly
680: */
681: int
682: sys_socketcall(int call, unsigned long *args)
683: {
684: switch (call) {
685: case SYS_SOCKET:
686: verify_area(args, 3 * sizeof(long));
687: return sock_socket(get_fs_long(args+0),
688: get_fs_long(args+1),
689: get_fs_long(args+2));
690:
691: case SYS_BIND:
692: verify_area(args, 3 * sizeof(long));
693: return sock_bind(get_fs_long(args+0),
694: (struct sockaddr *)get_fs_long(args+1),
695: get_fs_long(args+2));
696:
697: case SYS_CONNECT:
698: verify_area(args, 3 * sizeof(long));
699: return sock_connect(get_fs_long(args+0),
700: (struct sockaddr *)get_fs_long(args+1),
701: get_fs_long(args+2));
702:
703: case SYS_LISTEN:
704: verify_area(args, 2 * sizeof(long));
705: return sock_listen(get_fs_long(args+0),
706: get_fs_long(args+1));
707:
708: case SYS_ACCEPT:
709: verify_area(args, 3 * sizeof(long));
710: return sock_accept(get_fs_long(args+0),
711: (struct sockaddr *)get_fs_long(args+1),
712: (int *)get_fs_long(args+2));
713:
714: case SYS_GETSOCKNAME:
715: verify_area(args, 3 * sizeof(long));
716: return sock_getsockname(get_fs_long(args+0),
717: (struct sockaddr *)get_fs_long(args+1),
718: (int *)get_fs_long(args+2));
719:
720: case SYS_GETPEERNAME:
721: verify_area(args, 3 * sizeof(long));
722: return sock_getpeername(get_fs_long(args+0),
723: (struct sockaddr *)get_fs_long(args+1),
724: (int *)get_fs_long(args+2));
725:
726: case SYS_SOCKETPAIR:
727: verify_area(args, 4 * sizeof(long));
728: return sock_socketpair(get_fs_long(args+0),
729: get_fs_long(args+1),
730: get_fs_long(args+2),
731: (int *)get_fs_long(args+3));
732:
733: default:
734: return -EINVAL;
735: }
736: }
737:
738: void
739: sock_init(void)
740: {
741: struct socket *sock;
742: int i, ok;
743:
744: for (sock = sockets; sock <= last_socket; ++sock)
745: sock->state = SS_FREE;
746: for (i = ok = 0; i < NPROTO; ++i) {
747: printk("sock_init: initializing family %d (%s)\n",
748: proto_table[i].family, proto_table[i].name);
749: if ((*proto_table[i].ops->init)() < 0) {
750: printk("sock_init: init failed.\n",
751: proto_table[i].family);
752: proto_table[i].family = -1;
753: }
754: else
755: ++ok;
756: }
757: if (!ok)
758: printk("sock_init: warning: no protocols initialized\n");
759: return;
760: }
761:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.