Subversion Repositories Kolibri OS

Rev

Rev 4030 | Rev 4528 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  Part of the TCP/IP network stack for KolibriOS                 ;;
  7. ;;                                                                 ;;
  8. ;;   Written by hidnplayr@kolibrios.org                            ;;
  9. ;;                                                                 ;;
  10. ;;    Based on the code of 4.4BSD                                  ;;
  11. ;;                                                                 ;;
  12. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  13. ;;             Version 2, June 1991                                ;;
  14. ;;                                                                 ;;
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16.  
  17.  
  18. ;-------------------------
  19. ;
  20. ; TCP_usrclose
  21. ;
  22. ; Move connection to next state, based on process close.
  23. ;
  24. ;  IN:  eax = socket ptr
  25. ;
  26. ;-------------------------
  27. align 4
  28. TCP_usrclosed:
  29.  
  30.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_usrclosed: %x\n", eax
  31.  
  32.         push    ebx
  33.         mov     ebx, [eax + TCP_SOCKET.t_state]
  34.         mov     ebx, dword [.switch + ebx*4]
  35.         jmp     ebx
  36.  
  37.   .switch:
  38.  
  39.         dd      .close                  ; TCPS_CLOSED
  40.         dd      .close                  ; TCPS_LISTEN
  41.         dd      .close                  ; TCPS_SYN_SENT
  42.         dd      .wait1                  ; TCPS_SYN_RECEIVED
  43.         dd      .wait1                  ; TCPS_ESTABLISHED
  44.         dd      .last_ack               ; TCPS_CLOSE_WAIT
  45.         dd      .ret                    ; TCPS_FIN_WAIT_1
  46.         dd      .ret                    ; TCPS_CLOSING
  47.         dd      .ret                    ; TCPS_LAST_ACK
  48.         dd      .disc                   ; TCPS_FIN_WAIT_2
  49.         dd      .disc                   ; TCPS_TIMED_WAIT
  50.  
  51.  
  52.   .close:
  53.         mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
  54.         call    TCP_close
  55.         pop     ebx
  56.         ret
  57.  
  58.   .wait1:
  59.         mov     [eax + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
  60.         ; TODO: set timer?
  61.         pop     ebx
  62.         ret
  63.  
  64.   .last_ack:
  65.         mov     [eax + TCP_SOCKET.t_state], TCPS_LAST_ACK
  66.         pop     ebx
  67.         ret
  68.  
  69.   .disc:
  70.         call    SOCKET_is_disconnected
  71.         ; TODO: set timer?
  72.   .ret:
  73.         pop     ebx
  74.         ret
  75.  
  76.  
  77. ;-------------------------
  78. ;
  79. ; TCP_connect
  80. ;
  81. ;  IN:  eax = socket ptr
  82. ;  OUT: eax = 0 ok / -1 error
  83. ;       ebx = error code
  84. ;
  85. ;-------------------------
  86. align 4
  87. TCP_connect:
  88.  
  89.         test    [eax + SOCKET.state], SS_ISCONNECTED
  90.         jnz     .eisconn
  91.  
  92.         push    eax edx
  93.         lea     ecx, [eax + SOCKET.mutex]
  94.         call    mutex_lock
  95.         pop     edx eax
  96.  
  97. ; Fill in local IP
  98.         cmp     [eax + IP_SOCKET.LocalIP], 0
  99.         jne     @f
  100.         push    [IP_LIST + 4]                                   ; FIXME: use correct local IP
  101.         pop     [eax + IP_SOCKET.LocalIP]
  102.  
  103. ; Fill in remote port and IP
  104.         pushw   [edx + 2]
  105.         pop     [eax + TCP_SOCKET.RemotePort]
  106.  
  107.         pushd   [edx + 4]
  108.         pop     [eax + IP_SOCKET.RemoteIP]
  109.  
  110. ; Find a local port, if user didnt define one
  111.         cmp     [eax + TCP_SOCKET.LocalPort], 0
  112.         jne     @f
  113.         call    SOCKET_find_port
  114.        @@:
  115.  
  116. ; Start the TCP sequence
  117.         mov     [eax + TCP_SOCKET.timer_persist], 0
  118.         mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
  119.  
  120.         push    [TCP_sequence_num]
  121.         add     [TCP_sequence_num], 6400
  122.         pop     [eax + TCP_SOCKET.ISS]
  123.         mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
  124.  
  125.         TCP_sendseqinit eax
  126.  
  127.         mov     ebx, eax
  128.         lea     eax, [ebx + STREAM_SOCKET.snd]
  129.         call    SOCKET_ring_create
  130.         test    eax, eax
  131.         jz      .nomem
  132.  
  133.         lea     eax, [ebx + STREAM_SOCKET.rcv]
  134.         call    SOCKET_ring_create
  135.         test    eax, eax
  136.         jz      .nomem
  137.  
  138.         push    ebx
  139.         lea     ecx, [ebx + SOCKET.mutex]
  140.         call    mutex_unlock
  141.         pop     eax
  142.  
  143.         call    SOCKET_is_connecting
  144.  
  145. ; Now send the SYN packet to remote end
  146.         push    eax
  147.         call    TCP_output
  148.         pop     eax
  149.  
  150.   .block:
  151.         test    [eax + SOCKET.options], SO_NONBLOCK
  152.         jz      .waitforit
  153.  
  154.         xor     eax, eax
  155.         dec     eax
  156.         mov     ebx, EINPROGRESS
  157.         ret
  158.  
  159.   .nomem:
  160.         xor     eax, eax
  161.         dec     eax
  162.         mov     ebx, ENOMEM
  163.         ret
  164.  
  165.   .eisconn:
  166.         xor     eax, eax
  167.         dec     eax
  168.         mov     ebx, EISCONN
  169.         ret
  170.  
  171.   .waitforit:
  172.         push    eax
  173.         stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
  174.         pop     ebx
  175.         mov     [ebx + TCP_SOCKET.timer_connect], eax
  176.         mov     eax, ebx
  177.  
  178.   .loop:
  179.         cmp     [eax + SOCKET.errorcode], 0
  180.         jne     .fail
  181.         cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
  182.         je      .established
  183.  
  184.         call    SOCKET_block
  185.         jmp     .loop
  186.  
  187.   .timeout:
  188.         mov     eax, [esp+4]
  189.         mov     [eax + SOCKET.errorcode], ETIMEDOUT
  190.         and     [eax + SOCKET.state], not SS_ISCONNECTING
  191.         call    SOCKET_notify.unblock
  192.         ret     4
  193.  
  194.   .fail:
  195.         mov     ebx, [eax + SOCKET.errorcode]
  196.         mov     [eax + SOCKET.errorcode], 0                     ; Clear the error, we only need to send it to the caller once
  197.         xor     eax, eax
  198.         dec     eax
  199.         ret
  200.  
  201.   .established:
  202.         stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
  203.  
  204.         xor     eax, eax
  205.         ret
  206.  
  207.  
  208.  
  209.  
  210. ;-------------------------
  211. ;
  212. ; TCP_disconnect
  213. ;
  214. ;  IN:  eax = socket ptr
  215. ;  OUT: eax = socket ptr
  216. ;
  217. ;-------------------------
  218. align 4
  219. TCP_disconnect:
  220.  
  221.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_disconnect: %x\n", eax
  222.  
  223.         cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
  224.         jb      TCP_close
  225.  
  226.  
  227. ; TODO: implement LINGER ?
  228.  
  229.         call    SOCKET_is_disconnecting
  230.         call    TCP_usrclosed
  231.  
  232.         push    eax
  233.         call    TCP_output
  234.         pop     eax
  235.  
  236.         ret