Subversion Repositories Kolibri OS

Rev

Rev 3600 | Rev 3674 | 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. $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.         call    TCP_output
  156.  
  157. ;;; TODO: update stats
  158.  
  159.         jmp     TCP_close
  160.  
  161.   .no_syn_received:
  162.  
  163. ;;; TODO: update stats
  164.  
  165. ;;; TODO: check if error code is "Connection timed out' and handle accordingly
  166.  
  167.         mov     [eax + SOCKET.errorcode], ebx
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. ;-------------------------
  177. ;
  178. ; TCP_close
  179. ;
  180. ;  IN:  eax = socket ptr
  181. ;  OUT: eax = socket ptr
  182. ;
  183. ;-------------------------
  184. align 4
  185. TCP_close:
  186.  
  187.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_close: %x\n", eax
  188.  
  189. ;;; TODO: update RTT and mean deviation
  190. ;;; TODO: update slow start threshold
  191.  
  192.         call    SOCKET_is_disconnected
  193.         call    SOCKET_free
  194.  
  195.         ret
  196.  
  197.  
  198.  
  199.  
  200. ;-------------------------
  201. ;
  202. ; TCP_outflags
  203. ;
  204. ;  IN:  eax = socket ptr
  205. ;
  206. ;  OUT: edx = flags
  207. ;
  208. ;-------------------------
  209. align 4
  210. TCP_outflags:
  211.  
  212.         mov     edx, [eax + TCP_SOCKET.t_state]
  213.         movzx   edx, byte [edx + .flaglist]
  214.  
  215.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_outflags: socket=%x flags=%x\n", eax, dl
  216.  
  217.         ret
  218.  
  219.   .flaglist:
  220.  
  221.         db      TH_RST + TH_ACK         ; TCPS_CLOSED
  222.         db      0                       ; TCPS_LISTEN
  223.         db      TH_SYN                  ; TCPS_SYN_SENT
  224.         db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
  225.         db               TH_ACK         ; TCPS_ESTABLISHED
  226.         db               TH_ACK         ; TCPS_CLOSE_WAIT
  227.         db      TH_FIN + TH_ACK         ; TCPS_FIN_WAIT_1
  228.         db      TH_FIN + TH_ACK         ; TCPS_CLOSING
  229.         db      TH_FIN + TH_ACK         ; TCPS_LAST_ACK
  230.         db               TH_ACK         ; TCPS_FIN_WAIT_2
  231.         db               TH_ACK         ; TCPS_TIMED_WAIT
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238. ;---------------------------------------
  239. ;
  240. ; The fast way to send an ACK/RST/keepalive segment
  241. ;
  242. ; TCP_respond
  243. ;
  244. ;  IN:  ebx = socket ptr
  245. ;        cl = flags
  246. ;
  247. ;--------------------------------------
  248. align 4
  249. TCP_respond:
  250.  
  251.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: socket=%x flags=%x\n", ebx, cl
  252.  
  253. ;---------------------
  254. ; Create the IP packet
  255.  
  256.         push    cx ebx
  257.         mov     eax, [ebx + IP_SOCKET.RemoteIP]
  258.         mov     edx, [ebx + IP_SOCKET.LocalIP]
  259.         mov     ecx, sizeof.TCP_header
  260.         mov     di, IP_PROTO_TCP shl 8 + 128
  261.         call    IPv4_output
  262.         test    edi, edi
  263.         jz      .error
  264.         pop     esi cx
  265.         push    edx eax
  266.  
  267. ;-----------------------------------------------
  268. ; Fill in the TCP header by using the socket ptr
  269.  
  270.         mov     ax, [esi + TCP_SOCKET.LocalPort]
  271.         stosw
  272.         mov     ax, [esi + TCP_SOCKET.RemotePort]
  273.         stosw
  274.         mov     eax, [esi + TCP_SOCKET.SND_NXT]
  275.         bswap   eax
  276.         stosd
  277.         mov     eax, [esi + TCP_SOCKET.RCV_NXT]
  278.         bswap   eax
  279.         stosd
  280.         mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
  281.         stosb
  282.         mov     al, cl
  283.         stosb
  284. ;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
  285. ;        rol     ax, 8
  286.         mov     ax, 0x00a0      ;;;;;;; FIXME
  287.         stosw                   ; window
  288.         xor     eax, eax
  289.         stosd                   ; checksum + urgentpointer
  290.  
  291. ;---------------------
  292. ; Fill in the checksum
  293.  
  294.   .checksum:
  295.         sub     edi, sizeof.TCP_header
  296.         mov     ecx, sizeof.TCP_header
  297.         xchg    esi, edi
  298.         TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
  299.         mov     [esi+TCP_header.Checksum], dx
  300.  
  301. ;--------------------
  302. ; And send the segment
  303.  
  304.         call    [ebx + NET_DEVICE.transmit]
  305.         test    eax, eax
  306.         jnz     @f
  307.         call    NET_ptr_to_num4
  308.         inc     [TCP_segments_tx + edi]
  309.        @@:
  310.         ret
  311.  
  312.   .error:
  313.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: failed\n"
  314.         add     esp, 2 + 4
  315.  
  316.         ret
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325. ;-------------------------
  326. ; TCP_respond_segment:
  327. ;
  328. ;  IN:  edx = segment ptr (a previously received segment)
  329. ;       edi = ptr to dest and src IPv4 addresses
  330. ;        cl = flags
  331.  
  332. align 4
  333. TCP_respond_segment:
  334.  
  335.         DEBUGF  DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl
  336.  
  337. ;---------------------
  338. ; Create the IP packet
  339.  
  340.         push    cx edx
  341.         mov     ebx, [edi + 4]
  342.         mov     eax, [edi]
  343.         mov     ecx, sizeof.TCP_header
  344.         mov     di, IP_PROTO_TCP shl 8 + 128
  345.         call    IPv4_output
  346.         jz      .error
  347.         pop     esi cx
  348.  
  349.         push    edx eax
  350.  
  351. ;---------------------------------------------------
  352. ; Fill in the TCP header by using a received segment
  353.  
  354.         mov     ax, [esi + TCP_header.DestinationPort]
  355.         stosw
  356.         mov     ax, [esi + TCP_header.SourcePort]
  357.         stosw
  358.         mov     eax, [esi + TCP_header.AckNumber]
  359.         bswap   eax
  360.         stosd
  361.         xor     eax, eax
  362.         stosd
  363.         mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header/4 shl 4)
  364.         stosb
  365.         mov     al, cl
  366.         stosb
  367.         mov     ax, 1280
  368.         rol     ax, 8
  369.         stosw                   ; window
  370.         xor     eax, eax
  371.         stosd                   ; checksum + urgentpointer
  372.  
  373. ;---------------------
  374. ; Fill in the checksum
  375.  
  376.         lea     esi, [edi - sizeof.TCP_header]
  377.         mov     ecx, sizeof.TCP_header
  378.         TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
  379.                      (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
  380.         mov     [esi + TCP_header.Checksum], dx
  381.  
  382. ;--------------------
  383. ; And send the segment
  384.  
  385.         call    [ebx + NET_DEVICE.transmit]
  386.         test    eax, eax
  387.         jnz     @f
  388.         call    NET_ptr_to_num4
  389.         inc     [TCP_segments_tx + edi]
  390.        @@:
  391.         ret
  392.  
  393.   .error:
  394.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: failed\n"
  395.         add     esp, 2+4
  396.  
  397.         ret
  398.  
  399.  
  400. macro   TCPT_RANGESET   timer, value, min, max {
  401.  
  402. local   .min
  403. local   .max
  404. local   .done
  405.  
  406.         cmp     value, min
  407.         jb      .min
  408.         cmp     value, max
  409.         ja      .max
  410.  
  411.         mov     timer, value
  412.         jmp     .done
  413.  
  414.   .min:
  415.         mov     timer, value
  416.         jmp     .done
  417.  
  418.   .max:
  419.         mov     timer, value
  420.         jmp     .done
  421.  
  422.   .done:
  423. }
  424.  
  425.  
  426. align 4
  427. TCP_set_persist:
  428.  
  429.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_set_persist\n"
  430.  
  431. ; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive
  432.  
  433.         test    [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
  434.         jnz     .exit
  435.  
  436. ; calculate RTO
  437.         push    ebx
  438.         mov     ebx, [eax + TCP_SOCKET.t_srtt]
  439.         shr     ebx, 2
  440.         add     ebx, [eax + TCP_SOCKET.t_rttvar]
  441.         shr     ebx, 1
  442.  
  443.         mov     cl, [eax + TCP_SOCKET.t_rxtshift]
  444.         shl     ebx, cl
  445.  
  446. ; Start/restart persistance timer.
  447.  
  448.         TCPT_RANGESET   [eax + TCP_SOCKET.timer_persist], ebx, TCP_time_pers_min, TCP_time_pers_max
  449.         or      [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
  450.         pop     ebx
  451.  
  452.         cmp     [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift
  453.         jae     @f
  454.         inc     [eax + TCP_SOCKET.t_rxtshift]
  455.       @@:
  456.   .exit:
  457.  
  458.         ret
  459.  
  460.  
  461.  
  462. ; eax = rtt
  463. ; ebx = socket ptr
  464.  
  465. align 4
  466. TCP_xmit_timer:
  467.  
  468.         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
  469.  
  470. ;TODO: update stats
  471.  
  472.         cmp     [ebx + TCP_SOCKET.t_rtt], 0
  473.         je      .no_rtt_yet
  474.  
  475. ; srtt is stored as a fixed point with 3 bits after the binary point.
  476. ; The following magic is equivalent of the smoothing algorithm in rfc793 with an alpha of .875
  477. ; (srtt = rtt/8 + srtt*7/8 in fixed point)
  478. ; Adjust rtt to origin 0.
  479.  
  480.         push    ecx
  481.         mov     ecx, [ebx + TCP_SOCKET.t_srtt]
  482.         shr     ecx, TCP_RTT_SHIFT
  483.         sub     eax, ecx
  484.         dec     eax
  485.         pop     ecx
  486.  
  487.         add     [ebx + TCP_SOCKET.t_srtt], eax
  488.         ja      @f
  489.         mov     [ebx + TCP_SOCKET.t_srtt], 1
  490.   @@:
  491.  
  492. ; We accumulate a smoothed rtt variance (actually, a smoothed mean difference),
  493. ; then set the retransmit timer to smoothed rtt + 4 times the smoothed variance.
  494. ; rttvar is stored as fixed point with 2 bits after the binary point.
  495. ; The following is equivalent to rfc793 smoothing with an alpha of .75
  496. ; (rttvar = rttvar*3/4 + delta/4) (delta = eax)
  497.  
  498. ; get abs(eax)
  499.         push    edx
  500.         cdq
  501.         xor     eax, edx
  502.         sub     eax, edx
  503.  
  504.         mov     edx, [ebx + TCP_SOCKET.t_rttvar]
  505.         shr     edx, TCP_RTTVAR_SHIFT
  506.         sub     eax, edx
  507.         pop     edx
  508.  
  509.         add     [ebx + TCP_SOCKET.t_rttvar], eax
  510.         ja      @f
  511.         mov     [ebx + TCP_SOCKET.t_rttvar], 1
  512.   @@:
  513.         ret
  514.  
  515.  
  516.   .no_rtt_yet:
  517.  
  518.         push    ecx
  519.         mov     ecx, eax
  520.         shl     ecx, TCP_RTT_SHIFT
  521.         mov     [ebx + TCP_SOCKET.t_srtt], ecx
  522.  
  523.         shl     eax, TCP_RTTVAR_SHIFT - 1
  524.         mov     [ebx + TCP_SOCKET.t_rttvar], eax
  525.         pop     ecx
  526.  
  527.         ret
  528.  
  529.  
  530.  
  531.  
  532. ; eax = max segment size
  533. ; ebx = socket ptr
  534. align 4
  535. TCP_mss:
  536.  
  537.         cmp     eax, 1420                               ; FIXME
  538.         jbe     @f
  539.         mov     eax, 1420
  540.   @@:
  541.         mov     [ebx + TCP_SOCKET.t_maxseg], eax
  542.  
  543.  
  544.         ret
  545.  
  546.  
  547.  
  548.  
  549. ; ebx = socket ptr
  550. ; edx = segment ptr
  551. align 4
  552. TCP_reassemble:
  553.  
  554.  
  555.  
  556.         ret
  557.  
  558.