Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2013. 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. $Revision: 3514 $
  18.  
  19. align 4
  20. iglobal
  21.         TCP_backoff     db 0,1,2,3,4,5,6,6,6,6,6,6,6
  22. endg
  23.  
  24. macro   TCP_checksum IP1, IP2 {
  25.  
  26. ;-------------
  27. ; Pseudoheader
  28.  
  29.         ; protocol type
  30.         mov     edx, IP_PROTO_TCP
  31.  
  32.         ; source address
  33.         add     dl, byte [IP1+1]
  34.         adc     dh, byte [IP1+0]
  35.         adc     dl, byte [IP1+3]
  36.         adc     dh, byte [IP1+2]
  37.  
  38.         ; destination address
  39.         adc     dl, byte [IP2+1]
  40.         adc     dh, byte [IP2+0]
  41.         adc     dl, byte [IP2+3]
  42.         adc     dh, byte [IP2+2]
  43.  
  44.         ; size
  45.         adc     dl, cl
  46.         adc     dh, ch
  47.  
  48.         adc     edx, 0
  49.  
  50. ;---------------------
  51. ; Real header and data
  52.  
  53.         push    esi
  54.         call    checksum_1
  55.         call    checksum_2
  56.         pop     esi
  57.  
  58. }       ; returns in dx only
  59.  
  60.  
  61.  
  62.  
  63. macro   TCP_sendseqinit ptr {
  64.  
  65.         push    edi                     ;;;; i dont like this static use of edi
  66.         mov     edi, [ptr + TCP_SOCKET.ISS]
  67.         mov     [ptr + TCP_SOCKET.SND_UP], edi
  68.         mov     [ptr + TCP_SOCKET.SND_MAX], edi
  69.         mov     [ptr + TCP_SOCKET.SND_NXT], edi
  70.         mov     [ptr + TCP_SOCKET.SND_UNA], edi
  71.         pop     edi
  72.  
  73. }
  74.  
  75.  
  76.  
  77. macro   TCP_rcvseqinit ptr {
  78.  
  79.         push    edi
  80.         mov     edi, [ptr + TCP_SOCKET.IRS]
  81.         inc     edi
  82.         mov     [ptr + TCP_SOCKET.RCV_NXT], edi
  83.         mov     [ptr + TCP_SOCKET.RCV_ADV], edi
  84.         pop     edi
  85.  
  86. }
  87.  
  88.  
  89.  
  90. macro   TCP_init_socket socket {
  91.  
  92.         mov     [socket + TCP_SOCKET.t_maxseg], TCP_mss_default
  93.         mov     [socket + TCP_SOCKET.t_flags], TF_REQ_SCALE or TF_REQ_TSTMP
  94.  
  95.         mov     [socket + TCP_SOCKET.t_srtt], TCP_time_srtt_default
  96.         mov     [socket + TCP_SOCKET.t_rttvar], TCP_time_rtt_default * 4
  97.         mov     [socket + TCP_SOCKET.t_rttmin], TCP_time_re_min
  98. ;;; TODO: TCP_time_rangeset
  99.  
  100.         mov     [socket + TCP_SOCKET.SND_CWND], TCP_max_win shl TCP_max_winshift
  101.         mov     [socket + TCP_SOCKET.SND_SSTHRESH], TCP_max_win shl TCP_max_winshift
  102.  
  103.  
  104. }
  105.  
  106.  
  107. ;---------------------------
  108. ;
  109. ; TCP_pull_out_of_band
  110. ;
  111. ; IN:  eax =
  112. ;      ebx = socket ptr
  113. ;      edx = tcp packet ptr
  114. ;
  115. ; OUT: /
  116. ;
  117. ;---------------------------
  118.  
  119. align 4
  120. TCP_pull_out_of_band:
  121.  
  122.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_pull_out_of_band\n"
  123.  
  124.         ;;;; 1282-1305
  125.  
  126.         ret
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135. ;-------------------------
  136. ;
  137. ; TCP_drop
  138. ;
  139. ;  IN:  eax = socket ptr
  140. ;       ebx = error number
  141. ;
  142. ;  OUT: eax = socket ptr
  143. ;
  144. ;-------------------------
  145. align 4
  146. TCP_drop:
  147.  
  148.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
  149.  
  150.         cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
  151.         jb      .no_syn_received
  152.  
  153.         mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
  154.  
  155.         push    eax
  156.         call    TCP_output
  157.         pop     eax
  158.  
  159. ;;; TODO: update stats
  160.  
  161.         jmp     TCP_close
  162.  
  163.   .no_syn_received:
  164.  
  165. ;;; TODO: update stats
  166.  
  167. ;;; TODO: check if error code is "Connection timed out' and handle accordingly
  168.  
  169. ;        mov     [eax + SOCKET.errorcode], ebx
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178. ;-------------------------
  179. ;
  180. ; TCP_close
  181. ;
  182. ;  IN:  eax = socket ptr
  183. ;  OUT: eax = socket ptr
  184. ;
  185. ;-------------------------
  186. align 4
  187. TCP_close:
  188.  
  189.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_close: %x\n", eax
  190.  
  191. ;;; TODO: update RTT and mean deviation
  192. ;;; TODO: update slow start threshold
  193.  
  194.         call    SOCKET_is_disconnected
  195. ;;        call    SOCKET_free
  196.  
  197.         ret
  198.  
  199.  
  200.  
  201.  
  202. ;-------------------------
  203. ;
  204. ; TCP_outflags
  205. ;
  206. ;  IN:  eax = socket ptr
  207. ;
  208. ;  OUT: edx = flags
  209. ;
  210. ;-------------------------
  211. align 4
  212. TCP_outflags:
  213.  
  214.         mov     edx, [eax + TCP_SOCKET.t_state]
  215.         movzx   edx, byte [edx + .flaglist]
  216.  
  217.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_outflags: socket=%x flags=%x\n", eax, dl
  218.  
  219.         ret
  220.  
  221.   .flaglist:
  222.  
  223.         db      TH_RST + TH_ACK         ; TCPS_CLOSED
  224.         db      0                       ; TCPS_LISTEN
  225.         db      TH_SYN                  ; TCPS_SYN_SENT
  226.         db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
  227.         db               TH_ACK         ; TCPS_ESTABLISHED
  228.         db               TH_ACK         ; TCPS_CLOSE_WAIT
  229.         db      TH_FIN + TH_ACK         ; TCPS_FIN_WAIT_1
  230.         db      TH_FIN + TH_ACK         ; TCPS_CLOSING
  231.         db      TH_FIN + TH_ACK         ; TCPS_LAST_ACK
  232.         db               TH_ACK         ; TCPS_FIN_WAIT_2
  233.         db               TH_ACK         ; TCPS_TIMED_WAIT
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240. ;---------------------------------------
  241. ;
  242. ; The fast way to send an ACK/RST/keepalive segment
  243. ;
  244. ; TCP_respond
  245. ;
  246. ;  IN:  ebx = socket ptr
  247. ;        cl = flags
  248. ;
  249. ;--------------------------------------
  250. align 4
  251. TCP_respond:
  252.  
  253.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: socket=%x flags=%x\n", ebx, cl
  254.  
  255. ;---------------------
  256. ; Create the IP packet
  257.  
  258.         push    cx ebx
  259.         mov     eax, [ebx + IP_SOCKET.RemoteIP]
  260.         mov     edx, [ebx + IP_SOCKET.LocalIP]
  261.         mov     ecx, sizeof.TCP_header
  262.         mov     di, IP_PROTO_TCP shl 8 + 128
  263.         call    IPv4_output
  264.         test    edi, edi
  265.         jz      .error
  266.         pop     esi cx
  267.         push    edx eax
  268.  
  269. ;-----------------------------------------------
  270. ; Fill in the TCP header by using the socket ptr
  271.  
  272.         mov     ax, [esi + TCP_SOCKET.LocalPort]
  273.         stosw
  274.         mov     ax, [esi + TCP_SOCKET.RemotePort]
  275.         stosw
  276.         mov     eax, [esi + TCP_SOCKET.SND_NXT]
  277.         bswap   eax
  278.         stosd
  279.         mov     eax, [esi + TCP_SOCKET.RCV_NXT]
  280.         bswap   eax
  281.         stosd
  282.         mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
  283.         stosb
  284.         mov     al, cl
  285.         stosb
  286. ;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
  287. ;        rol     ax, 8
  288.         mov     ax, 0x00a0      ;;;;;;; FIXME
  289.         stosw                   ; window
  290.         xor     eax, eax
  291.         stosd                   ; checksum + urgentpointer
  292.  
  293. ;---------------------
  294. ; Fill in the checksum
  295.  
  296.   .checksum:
  297.         sub     edi, sizeof.TCP_header
  298.         mov     ecx, sizeof.TCP_header
  299.         xchg    esi, edi
  300.         TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
  301.         mov     [esi+TCP_header.Checksum], dx
  302.  
  303. ;--------------------
  304. ; And send the segment
  305.  
  306.         call    [ebx + NET_DEVICE.transmit]
  307.         test    eax, eax
  308.         jnz     @f
  309.         call    NET_ptr_to_num4
  310.         inc     [TCP_segments_tx + edi]
  311.        @@:
  312.         ret
  313.  
  314.   .error:
  315.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: failed\n"
  316.         add     esp, 2 + 4
  317.  
  318.         ret
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327. ;-------------------------
  328. ; TCP_respond_segment:
  329. ;
  330. ;  IN:  edx = segment ptr (a previously received segment)
  331. ;       edi = ptr to dest and src IPv4 addresses
  332. ;        cl = flags
  333.  
  334. align 4
  335. TCP_respond_segment:
  336.  
  337.         DEBUGF  DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl
  338.  
  339. ;---------------------
  340. ; Create the IP packet
  341.  
  342.         push    cx edx
  343.         mov     edx, [edi + 4]
  344.         mov     eax, [edi]
  345.         mov     ecx, sizeof.TCP_header
  346.         mov     di, IP_PROTO_TCP shl 8 + 128
  347.         call    IPv4_output
  348.         jz      .error
  349.         pop     esi cx
  350.  
  351.         push    edx eax
  352.  
  353. ;---------------------------------------------------
  354. ; Fill in the TCP header by using a received segment
  355.  
  356.         mov     ax, [esi + TCP_header.DestinationPort]
  357.         stosw
  358.         mov     ax, [esi + TCP_header.SourcePort]
  359.         stosw
  360.         mov     eax, [esi + TCP_header.AckNumber]
  361.         bswap   eax
  362.         stosd
  363.         xor     eax, eax
  364.         stosd
  365.         mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header/4 shl 4)
  366.         stosb
  367.         mov     al, cl
  368.         stosb
  369.         mov     ax, 1280
  370.         rol     ax, 8
  371.         stosw                   ; window
  372.         xor     eax, eax
  373.         stosd                   ; checksum + urgentpointer
  374.  
  375. ;---------------------
  376. ; Fill in the checksum
  377.  
  378.         lea     esi, [edi - sizeof.TCP_header]
  379.         mov     ecx, sizeof.TCP_header
  380.         TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
  381.                      (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
  382.         mov     [esi + TCP_header.Checksum], dx
  383.  
  384. ;--------------------
  385. ; And send the segment
  386.  
  387.         call    [ebx + NET_DEVICE.transmit]
  388.         test    eax, eax
  389.         jnz     @f
  390.         call    NET_ptr_to_num4
  391.         inc     [TCP_segments_tx + edi]
  392.        @@:
  393.         ret
  394.  
  395.   .error:
  396.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: failed\n"
  397.         add     esp, 2+4
  398.  
  399.         ret
  400.  
  401.  
  402. macro   TCPT_RANGESET   timer, value, min, max {
  403.  
  404. local   .min
  405. local   .max
  406. local   .done
  407.  
  408.         cmp     value, min
  409.         jb      .min
  410.         cmp     value, max
  411.         ja      .max
  412.  
  413.         mov     timer, value
  414.         jmp     .done
  415.  
  416.   .min:
  417.         mov     timer, value
  418.         jmp     .done
  419.  
  420.   .max:
  421.         mov     timer, value
  422.         jmp     .done
  423.  
  424.   .done:
  425. }
  426.  
  427.  
  428. align 4
  429. TCP_set_persist:
  430.  
  431.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_set_persist\n"
  432.  
  433. ; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive
  434.  
  435.         test    [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
  436.         jnz     .exit
  437.  
  438. ; calculate RTO
  439.         push    ebx
  440.         mov     ebx, [eax + TCP_SOCKET.t_srtt]
  441.         shr     ebx, 2
  442.         add     ebx, [eax + TCP_SOCKET.t_rttvar]
  443.         shr     ebx, 1
  444.  
  445.         mov     cl, [eax + TCP_SOCKET.t_rxtshift]
  446.         shl     ebx, cl
  447.  
  448. ; Start/restart persistance timer.
  449.  
  450.         TCPT_RANGESET   [eax + TCP_SOCKET.timer_persist], ebx, TCP_time_pers_min, TCP_time_pers_max
  451.         or      [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
  452.         pop     ebx
  453.  
  454.         cmp     [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift
  455.         jae     @f
  456.         inc     [eax + TCP_SOCKET.t_rxtshift]
  457.       @@:
  458.   .exit:
  459.  
  460.         ret
  461.  
  462.  
  463.  
  464. ; eax = rtt
  465. ; ebx = socket ptr
  466.  
  467. align 4
  468. TCP_xmit_timer:
  469.  
  470.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
  471.  
  472. ;TODO: update stats
  473.  
  474.         cmp     [ebx + TCP_SOCKET.t_rtt], 0
  475.         je      .no_rtt_yet
  476.  
  477. ; srtt is stored as a fixed point with 3 bits after the binary point.
  478. ; The following magic is equivalent of the smoothing algorithm in rfc793 with an alpha of .875
  479. ; (srtt = rtt/8 + srtt*7/8 in fixed point)
  480. ; Adjust rtt to origin 0.
  481.  
  482.         push    ecx
  483.         mov     ecx, [ebx + TCP_SOCKET.t_srtt]
  484.         shr     ecx, TCP_RTT_SHIFT
  485.         sub     eax, ecx
  486.         dec     eax
  487.         pop     ecx
  488.  
  489.         add     [ebx + TCP_SOCKET.t_srtt], eax
  490.         ja      @f
  491.         mov     [ebx + TCP_SOCKET.t_srtt], 1
  492.   @@:
  493.  
  494. ; We accumulate a smoothed rtt variance (actually, a smoothed mean difference),
  495. ; then set the retransmit timer to smoothed rtt + 4 times the smoothed variance.
  496. ; rttvar is stored as fixed point with 2 bits after the binary point.
  497. ; The following is equivalent to rfc793 smoothing with an alpha of .75
  498. ; (rttvar = rttvar*3/4 + delta/4) (delta = eax)
  499.  
  500. ; get abs(eax)
  501.         push    edx
  502.         cdq
  503.         xor     eax, edx
  504.         sub     eax, edx
  505.  
  506.         mov     edx, [ebx + TCP_SOCKET.t_rttvar]
  507.         shr     edx, TCP_RTTVAR_SHIFT
  508.         sub     eax, edx
  509.         pop     edx
  510.  
  511.         add     [ebx + TCP_SOCKET.t_rttvar], eax
  512.         ja      @f
  513.         mov     [ebx + TCP_SOCKET.t_rttvar], 1
  514.   @@:
  515.         ret
  516.  
  517.  
  518.   .no_rtt_yet:
  519.  
  520.         push    ecx
  521.         mov     ecx, eax
  522.         shl     ecx, TCP_RTT_SHIFT
  523.         mov     [ebx + TCP_SOCKET.t_srtt], ecx
  524.  
  525.         shl     eax, TCP_RTTVAR_SHIFT - 1
  526.         mov     [ebx + TCP_SOCKET.t_rttvar], eax
  527.         pop     ecx
  528.  
  529.         ret
  530.  
  531.  
  532.  
  533.  
  534. ; eax = max segment size
  535. ; ebx = socket ptr
  536. align 4
  537. TCP_mss:
  538.  
  539.         cmp     eax, 1420                               ; FIXME
  540.         jbe     @f
  541.         mov     eax, 1420
  542.   @@:
  543.         mov     [ebx + TCP_SOCKET.t_maxseg], eax
  544.  
  545.  
  546.         ret
  547.  
  548.  
  549.  
  550.  
  551. ; ebx = socket ptr
  552. ; edx = segment ptr
  553. align 4
  554. TCP_reassemble:
  555.  
  556.  
  557.  
  558.         ret
  559.  
  560.