3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <net/packet.h>
29 #include <net/socket.h>
32 /* Mutex for socket function */
33 MUTEX_CREATE (mutex_tcp_accept
);
34 MUTEX_CREATE (mutex_tcp_read_cache
);
36 proto_tcp_conn_t proto_tcp_conn_list
;
37 proto_tcp_backlog_t proto_tcp_backlog_list
;
39 extern netif_t netif_list
;
41 static net_port proto_tcp_client_port
;
42 static unsigned short proto_tcp_dup
;
43 static unsigned proto_tcp_seq
;
44 static unsigned proto_tcp_fd
;
47 proto_tcp_conn_t
*net_proto_tcp_conn_check (net_ipv4 ip_source
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
, unsigned char *ret
);
48 int net_proto_tcp_conn_add ();
49 int net_proto_tcp_conn_set (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
);
50 int net_proto_tcp_conn_estabilish (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_ipv4 ip_dest
, net_port port_dest
);
51 int net_proto_tcp_conn_estabilish_reply (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
52 int net_proto_tcp_read_cache (proto_tcp_conn_t
*conn
, char *data
, unsigned len
);
53 int net_proto_tcp_read_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
);
54 int net_proto_tcp_write (netif_t
*eth
, net_ipv4 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
);
55 int net_proto_tcp_write_data (proto_tcp_conn_t
*conn
, char *data
, unsigned len
);
56 int net_proto_tcp_write_data_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
57 int net_proto_tcp_conn_disconnected (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
);
58 int net_proto_tcp_conn_close (proto_tcp_conn_t
*conn
);
59 unsigned net_proto_tcp_conn_del (proto_tcp_conn_t
*conn
);
60 proto_tcp_conn_t
*net_proto_tcp_conn_find (int fd
);
61 int net_proto_tcp_backlog_add (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
);
62 int net_proto_tcp_conn_invite (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
);
65 * User-friendly socket functions
67 int net_proto_tcp_socket ()
69 return net_proto_tcp_conn_add ();
72 extern unsigned long timer_ticks
;
73 int net_proto_tcp_connect (int fd
, sockaddr_in
*addr
)
77 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
83 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
84 ret
= net_proto_tcp_conn_estabilish (conn
, netif
, addr
->sin_addr
, addr
->sin_port
);
86 unsigned long stime
= timer_ticks
;
89 if (!(conn
->flags
& O_NONBLOCK
)) {
97 if ((stime
+3000) < timer_ticks
)
100 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHED
)
103 /* when connection cant be accepted succefully first time, try it again */
104 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISHERROR
) {
105 ret
= net_proto_tcp_conn_estabilish (conn
, netif
, addr
->sin_addr
, addr
->sin_port
);
106 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
110 /* non-blocking mode */
119 int net_proto_tcp_send (int fd
, char *msg
, unsigned size
)
121 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
126 int ret
= net_proto_tcp_write_data (conn
, msg
, size
);
129 unsigned long stime
= timer_ticks
;
132 if (!(conn
->flags
& O_NONBLOCK
)) {
133 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
135 if ((stime
+350) < timer_ticks
)
142 /* non-blocking mode */
144 while (conn
->state
!= PROTO_TCP_CONN_STATE_READY
) {
146 if ((stime
+100) < timer_ticks
)
155 int net_proto_tcp_recv (int fd
, char *msg
, unsigned size
)
157 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
164 //kprintf ("recv () - %d\n", fd);
167 if (!(conn
->flags
& O_NONBLOCK
)) {
168 while (!conn
->len
/* || conn->state != PROTO_TCP_CONN_STATE_READY*/) {
169 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
170 if (net_proto_tcp_conn_del (conn
));
177 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
) {
178 if (net_proto_tcp_conn_del (conn
));
186 if ((conn
->len
-conn
->offset
) > size
) {
187 memcpy (msg
, conn
->data
+conn
->offset
, size
);
188 //printf ("msg: %d %d\n", conn->offset, size);
189 conn
->offset
+= size
;
195 memcpy (msg
, conn
->data
+conn
->offset
, conn
->len
-conn
->offset
);
196 //printf ("msg2: %d %d\n", conn->offset, size);
203 //kprintf ("recv () - %d -- DATA: %d\n", fd, ret);
208 int net_proto_tcp_close (int fd
)
210 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
215 if (conn
->state
== PROTO_TCP_CONN_STATE_DISCONNECTED
)
218 int ret
= net_proto_tcp_conn_close (conn
);
223 int net_proto_tcp_fcntl (int fd
, int cmd
, long arg
)
225 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
241 int net_proto_tcp_bind (int fd
, sockaddr_in
*addr
, socklen_t len
)
243 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
249 for (netif
= netif_list
.next
; netif
!= &netif_list
; netif
= netif
->next
) {
250 net_proto_tcp_conn_set (conn
, netif
, addr
->sin_port
, 0, 0);
258 int net_proto_tcp_listen (int fd
, int backlog
)
260 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
268 int net_proto_tcp_accept (int fd
, sockaddr_in
*addr
, socklen_t
*addrlen
)
270 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_find (fd
);
277 proto_tcp_backlog_t
*backlog
= 0;
280 if (!(conn
->flags
& O_NONBLOCK
)) {
282 for (backlog
= proto_tcp_backlog_list
.next
; backlog
!= &proto_tcp_backlog_list
; backlog
= backlog
->next
) {
283 if (backlog
->conn
== conn
) {
292 /* non-blocking mode */
293 for (backlog
= proto_tcp_backlog_list
.next
; backlog
!= &proto_tcp_backlog_list
; backlog
= backlog
->next
) {
294 if (backlog
->conn
== conn
) {
301 //printf ("accept ()\n");
306 net_ipv4 ip
= backlog
->ip
;
307 net_port port
= backlog
->port
;
308 unsigned seq
= backlog
->seq
;
310 int ret
= net_proto_tcp_conn_invite (conn
, ip
, port
, seq
);
312 /* remove from queue accepted connection */
313 backlog
->next
->prev
= backlog
->prev
;
314 backlog
->prev
->next
= backlog
->next
;
321 int fd_new
= net_proto_tcp_conn_add ();
326 proto_tcp_conn_t
*conn_new
= net_proto_tcp_conn_find (fd_new
);
331 net_proto_tcp_conn_set (conn_new
, conn
->netif
, conn
->port_source
, conn
->netif
->ip
, port
);
333 conn_new
->ip_dest
= ip
;
336 addr
->sin_port
= port
;
337 addr
->sin_family
= AF_INET
;
343 * Hardcore code - syn, ack, psh, fin, etc :P
345 unsigned net_proto_tcp_handler (packet_t
*packet
, proto_ip_t
*ip
, char *buf
, unsigned len
)
347 proto_tcp_t
*tcp
= (proto_tcp_t
*) buf
;
349 unsigned char ret
= 0;
351 /* First check ip address and ports, that we want this data */
352 proto_tcp_conn_t
*conn
= net_proto_tcp_conn_check (ip
->ip_dest
, tcp
->port_dest
, ip
->ip_source
, tcp
->port_source
, &ret
);
354 if (!conn
&& ret
== 0)
357 //printf ("tcp->flags: 0x%x, ret: %d, conn: 0x%x, fd: %d\n", tcp->flags, ret, conn, conn->fd);
359 /* connection from client before accept () */
361 /* client want connect to our server */
362 if (tcp
->flags
== 0x02) {
363 mutex_lock (&mutex_tcp_accept
);
365 unsigned ret
= net_proto_tcp_backlog_add (conn
, ip
->ip_source
, tcp
->port_source
, tcp
->seq
);
367 mutex_unlock (&mutex_tcp_accept
);
375 unsigned data_cache
= 0;
378 if (tcp
->flags
& 0x08) {
379 /* needed for calculate real offset from 4bit number */
380 unsigned offset
= tcp
->data_offset
* 4;
382 /* now calculate accurate length of tcp _data_ */
383 unsigned size
= swap16 (ip
->total_len
) - (offset
+ (ip
->head_len
*4));
384 //kprintf (">>>> %d : %d : %d\n", offset, size, len);
385 //mutex_lock (&mutex_tcp_read_cache);
386 net_proto_tcp_read_cache (conn
, buf
+offset
, size
);
387 //mutex_unlock (&mutex_tcp_read_cache);
389 net_proto_tcp_read_ok (conn
, ip
, tcp
, size
);
394 /* sended data was delivered succefully */
395 if (tcp
->flags
& 0x10) {
396 /* HACK: It is interesting, that no push flag, and there could be some data to read */
398 /* needed for calculate real offset from 4bit number */
399 unsigned offset
= tcp
->data_offset
* 4;
401 /* now calculate accurate length of tcp _data_ */
402 unsigned size
= swap16 (ip
->total_len
) - (offset
+ (ip
->head_len
*4));
404 /* there are data for read */
406 /* data was cached, so no need cache it again */
408 //kprintf (">>>>2 %d : %d : %d\n", offset, size, len);
409 mutex_lock (&mutex_tcp_read_cache
);
410 net_proto_tcp_read_cache (conn
, buf
+offset
, size
);
411 mutex_unlock (&mutex_tcp_read_cache
);
413 net_proto_tcp_read_ok (conn
, ip
, tcp
, size
);
416 /* when data are'nt available, lets normal work - acknowledgement */
417 if (conn
->state
== PROTO_TCP_CONN_STATE_ESTABILISH
) {
418 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHERROR
;
419 net_proto_tcp_write_data_ok (conn
, ip
, tcp
);
421 net_proto_tcp_write_data_ok (conn
, ip
, tcp
);
425 /* connection estabilish respond */
426 if (tcp
->flags
== 0x12) {
427 return net_proto_tcp_conn_estabilish_reply (conn
, ip
, tcp
);
430 /* another side close connection */
431 if (tcp
->flags
& 0x01) {
432 DPRINT ("TCP -> fd %d connection closed by remote host\n", conn
->fd
);
433 net_proto_tcp_conn_disconnected (conn
, ip
, tcp
); // FIXME: problem in server with hangind the whole program
436 /* another side close connection */
437 if (tcp
->flags
& 0x04) {
438 DPRINT ("TCP -> fd %d connection reseted by peer\n", conn
->fd
);
439 net_proto_tcp_conn_disconnected (conn
, ip
, tcp
);
445 int net_proto_tcp_read_cache (proto_tcp_conn_t
*conn
, char *data
, unsigned len
)
447 if (!data
|| !conn
|| !len
)
451 conn
->data
= (char *) kmalloc (sizeof (char) * (len
+ 1));
453 memcpy (conn
->data
, data
, len
);
455 char *newdata
= (char *) kmalloc (sizeof (char) * (conn
->len
+ len
+ 1));
460 memcpy (newdata
, conn
->data
, conn
->len
);
461 memcpy (newdata
+conn
->len
, data
, len
);
465 conn
->data
= newdata
;
471 //kprintf ("DATA: %d - #'%s'#\n", len, data);
475 conn
->data
[conn
->len
] = '\0';
480 int net_proto_tcp_read_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
, unsigned len
)
482 if (!ip_old
|| !tcp_old
|| !conn
)
485 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
490 tcp
->port_source
= conn
->port_source
; // increase client port too
491 tcp
->port_dest
= conn
->port_dest
;
493 tcp
->seq
= tcp_old
->ack
;
495 /* this small thing did bad work when e.g. 10 10 10 fe get to calculation,
496 it returns 10 10 10 08, no 10 10 11 08 */
497 unsigned seq
= swap32 (tcp_old
->seq
);
500 tcp
->ack
= swap32 (seq
);
503 tcp
->data_offset
= 5;
505 tcp
->window
= tcp_old
->window
+ swap16 (64);
508 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
510 /*if (proto_tcp_dup == tcp_old->checksum) {
511 printf ("Duplicated packet :)");
516 //printf ("read_ok: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
518 conn
->seq
= tcp
->ack
;
519 conn
->ack
= tcp
->seq
;
521 //printf ("read_ok2: seq: 0x%x | ack: 0x%x\n", conn->seq, conn->ack);
523 proto_tcp_dup
= tcp_old
->checksum
;
533 int net_proto_tcp_write (netif_t
*eth
, net_ipv4 dest
, proto_tcp_t
*tcp
, char *data
, unsigned len
)
543 unsigned get
= arp_cache_get (dest
, &mac_dest
);
546 arp_send_request (eth
, dest
);
549 /* 100ms for waiting on ARP reply */
551 get
= arp_cache_get (dest
, &mac_dest
);
556 /* TODO: make better waiting for ARP reply */
569 packet_t
*packet
= (packet_t
*) kmalloc (sizeof (packet_t
));
574 memcpy (&packet
->mac_source
, eth
->dev
->dev_addr
, 6);
575 memcpy (&packet
->mac_dest
, mac_dest
, 6);
576 packet
->type
= NET_PACKET_TYPE_IPV4
;
579 proto_ip_t
*ip
= (proto_ip_t
*) kmalloc (sizeof (proto_ip_t
));
584 /* there are some fixed values - yeah it is horrible */
592 ip
->proto
= NET_PROTO_IP_TYPE_TCP
;
593 ip
->ip_source
= eth
->ip
;
596 unsigned l
= (tcp
->data_offset
*4);
598 /* calculate total length of packet (tcp/ip) */
599 ip
->total_len
= swap16 (l
+sizeof (proto_tcp_t
)+len
);
601 char *buf_tcp
= (char *) kmalloc ((len
+l
+1) * sizeof (char));
606 memcpy (buf_tcp
, (char *) tcp
, l
);
609 memcpy (buf_tcp
+l
, data
, len
);
611 buf_tcp
[l
+len
] = '\0';
613 /* calculate checksum and put it to tcp header */
614 proto_tcp_t
*tcp_
= (proto_tcp_t
*) buf_tcp
;
616 tcp_
->checksum
= checksum16_tcp (eth
->ip
, dest
, buf_tcp
, l
+len
);
618 /* send tcp header+data to ip layer */
619 unsigned ret
= net_proto_ip_send (eth
, packet
, ip
, (char *) buf_tcp
, l
+len
);
628 int net_proto_tcp_write_data (proto_tcp_conn_t
*conn
, char *data
, unsigned len
)
630 if (!conn
|| !len
|| !data
)
633 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
638 tcp
->port_source
= conn
->port_source
;
639 tcp
->port_dest
= conn
->port_dest
;
641 unsigned seq
= swap32 (proto_tcp_seq
);
644 //tcp->ack = swap32 (seq);
646 proto_tcp_seq
= swap32 (seq
);
649 tcp
->seq
= conn
->seq
;
650 tcp
->ack
= conn
->ack
;
652 tcp
->seq
= conn
->ack
;
653 tcp
->ack
= conn
->seq
;
658 //printf ("TCP -> seq: 0x%x | ack: 0x%x | proto_seq: 0x%x\n", tcp->seq, conn->ack, proto_tcp_seq);
661 tcp
->data_offset
= 5;
663 tcp
->window
= swap16 (32768);
666 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, data
, len
);
671 conn
->state
= PROTO_TCP_CONN_STATE_WAIT
;
676 int net_proto_tcp_write_data_ok (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
678 if (!ip_old
|| !tcp_old
|| !conn
)
681 /* cross - because we change now sides :) */
682 conn
->seq
= tcp_old
->ack
;
683 conn
->ack
= tcp_old
->seq
;
685 //printf ("data_ok: seq: 0x%x | ack: 0x%x\n", tcp_old->ack, tcp_old->seq);
687 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
692 /* try connect to server */
693 int net_proto_tcp_conn_estabilish (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_ipv4 ip_dest
, net_port port_dest
)
698 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
703 tcp
->port_source
= swap16 (proto_tcp_client_port
); // increase client port too
704 tcp
->port_dest
= port_dest
;
706 /* setup new connection */
707 net_proto_tcp_conn_set (conn
, eth
, tcp
->port_source
, ip_dest
, tcp
->port_dest
);
709 tcp
->seq
= conn
->seq
;
710 tcp
->ack
= conn
->ack
;
713 tcp
->data_offset
= 5;
715 tcp
->window
= swap16 (32792);
718 int ret
= net_proto_tcp_write (eth
, ip_dest
, tcp
, 0, 0);
723 net_proto_tcp_conn_del (conn
);
730 int net_proto_tcp_conn_estabilish_reply (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
732 if (!ip_old
|| !tcp_old
|| !conn
)
735 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
740 tcp
->port_source
= conn
->port_source
; // increase client port too
741 tcp
->port_dest
= conn
->port_dest
;
743 tcp
->seq
= tcp_old
->ack
;
744 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
747 tcp
->data_offset
= 5;
749 tcp
->window
= tcp_old
->window
+ swap16 (64);
752 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
755 conn
->seq
= tcp
->seq
;
756 conn
->ack
= tcp
->ack
;
757 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISHED
;
760 DPRINT ("TCP -> fd %ï connected to server succefully\n", conn
->fd
);
767 int net_proto_tcp_conn_disconnected (proto_tcp_conn_t
*conn
, proto_ip_t
*ip_old
, proto_tcp_t
*tcp_old
)
769 if (!ip_old
|| !tcp_old
|| !conn
)
772 if (conn
->state
== PROTO_TCP_CONN_STATE_CLOSE
)
773 return net_proto_tcp_conn_del (conn
);
775 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
780 tcp
->port_source
= conn
->port_source
; // increase client port too
781 tcp
->port_dest
= conn
->port_dest
;
783 tcp
->seq
= tcp_old
->ack
;
784 tcp
->ack
= tcp_old
->seq
+ swap32 (1);
787 tcp
->data_offset
= 5;
789 tcp
->window
= tcp_old
->window
+ swap16 (64);
792 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
797 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
; //ret = net_proto_tcp_conn_del (conn);
804 int net_proto_tcp_conn_close (proto_tcp_conn_t
*conn
)
809 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
814 tcp
->port_source
= conn
->port_source
; // increase client port too
815 tcp
->port_dest
= conn
->port_dest
;
817 tcp
->seq
= conn
->seq
;
818 tcp
->ack
= conn
->ack
;
821 tcp
->data_offset
= 5;
823 tcp
->window
= swap16 (32832);
826 int ret
= net_proto_tcp_write (conn
->netif
, conn
->ip_dest
, tcp
, 0, 0);
831 conn
->state
= PROTO_TCP_CONN_STATE_CLOSE
;
837 /* client wants to connect */
838 net_proto_tcp_conn_invite (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
)
843 proto_tcp_t
*tcp
= (proto_tcp_t
*) kmalloc (sizeof (proto_tcp_t
));
848 tcp
->port_source
= conn
->port_source
;
849 tcp
->port_dest
= port
;
851 tcp
->seq
= proto_tcp_seq
++;
852 tcp
->ack
= seq
+ swap32 (1);
855 tcp
->data_offset
= 5;
857 tcp
->window
= swap16 (5816);
860 int ret
= net_proto_tcp_write (conn
->netif
, ip
, tcp
, 0, 0);
865 conn
->state
= PROTO_TCP_CONN_STATE_READY
;
873 /* Create new TCP connection */
874 int net_proto_tcp_conn_add ()
876 proto_tcp_conn_t
*conn
;
878 /* alloc and init context */
879 conn
= (proto_tcp_conn_t
*) kmalloc (sizeof (proto_tcp_conn_t
));
884 memset (conn
, 0, sizeof (proto_tcp_conn_t
));
889 conn
->fd
= proto_tcp_fd
++;
894 conn
->next
= &proto_tcp_conn_list
;
895 conn
->prev
= proto_tcp_conn_list
.prev
;
896 conn
->prev
->next
= conn
;
897 conn
->next
->prev
= conn
;
902 /* Setup new connection */
903 int net_proto_tcp_conn_set (proto_tcp_conn_t
*conn
, netif_t
*eth
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
)
908 conn
->ip_source
= eth
->ip
;
909 conn
->ip_dest
= ip_dest
;
911 conn
->port_source
= port_source
;
912 conn
->port_dest
= port_dest
;
914 proto_tcp_seq
+= swap32 (1);
916 conn
->seq
= proto_tcp_seq
++;
919 conn
->state
= PROTO_TCP_CONN_STATE_ESTABILISH
;
930 /* Delete existing connection from list */
931 unsigned net_proto_tcp_conn_del (proto_tcp_conn_t
*conn
)
936 conn
->state
= PROTO_TCP_CONN_STATE_DISCONNECTED
;
943 conn
->next
->prev
= conn
->prev
;
944 conn
->prev
->next
= conn
->next
;
951 proto_tcp_conn_t
*net_proto_tcp_conn_check (net_ipv4 ip_source
, net_port port_source
, net_ipv4 ip_dest
, net_port port_dest
, unsigned char *ret
)
954 proto_tcp_conn_t
*conn
= NULL
;
955 proto_tcp_conn_t
*conn_ret
= NULL
;
956 //printf ("-------------------------\n");
957 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
959 net_proto_ip_print (conn->ip_source);
961 net_proto_ip_print (ip_source);
963 net_proto_ip_print (conn->ip_dest);
965 net_proto_ip_print (ip_dest);
966 printf ("\nporty: %d / %d\n", swap16 (conn->port_source), swap16 (port_source));
967 printf ("porty2: %d / %d\n", swap16 (conn->port_dest), swap16 (port_dest));*/
969 if (conn
->ip_source
== ip_source
&& conn
->port_source
== port_source
) {
970 if (conn
->ip_dest
== ip_dest
&& conn
->port_dest
== port_dest
) {
982 if (!conn_ret
->bind
) {
985 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
987 if (conn
->ip_source
== ip_source
&& conn
->port_source
== port_source
)
996 proto_tcp_conn_t
*net_proto_tcp_conn_find (int fd
)
998 proto_tcp_conn_t
*conn
= NULL
;
999 for (conn
= proto_tcp_conn_list
.next
; conn
!= &proto_tcp_conn_list
; conn
= conn
->next
) {
1007 /* Create new TCP backlog stamp */
1008 int net_proto_tcp_backlog_add (proto_tcp_conn_t
*conn
, net_ipv4 ip
, net_port port
, unsigned seq
)
1013 proto_tcp_backlog_t
*backlog
;
1015 /* alloc and init context */
1016 backlog
= (proto_tcp_backlog_t
*) kmalloc (sizeof (proto_tcp_backlog_t
));
1021 backlog
->conn
= conn
;
1023 backlog
->port
= port
;
1027 backlog
->next
= &proto_tcp_backlog_list
;
1028 backlog
->prev
= proto_tcp_backlog_list
.prev
;
1029 backlog
->prev
->next
= backlog
;
1030 backlog
->next
->prev
= backlog
;
1035 /* init of tcp protocol */
1036 unsigned init_net_proto_tcp ()
1038 proto_tcp_conn_list
.next
= &proto_tcp_conn_list
;
1039 proto_tcp_conn_list
.prev
= &proto_tcp_conn_list
;
1041 proto_tcp_backlog_list
.next
= &proto_tcp_backlog_list
;
1042 proto_tcp_backlog_list
.prev
= &proto_tcp_backlog_list
;
1044 /* base tcp client port, which is used for client's use */
1045 proto_tcp_client_port
= 1024;
1046 proto_tcp_dup
= 0x0;
1047 proto_tcp_seq
= 0x1;
1048 proto_tcp_fd
= 1024;