Subversion Repositories Kolibri OS

Rev

Rev 2891 | Blame | 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: 2930 $
  18.  
  19. macro   TCP_checksum IP1, IP2 {
  20.  
  21. ;-------------
  22. ; Pseudoheader
  23.  
  24.         ; protocol type
  25.         mov     edx, IP_PROTO_TCP
  26.  
  27.         ; source address
  28.         add     dl, byte [IP1+1]
  29.         adc     dh, byte [IP1+0]
  30.         adc     dl, byte [IP1+3]
  31.         adc     dh, byte [IP1+2]
  32.  
  33.         ; destination address
  34.         adc     dl, byte [IP2+1]
  35.         adc     dh, byte [IP2+0]
  36.         adc     dl, byte [IP2+3]
  37.         adc     dh, byte [IP2+2]
  38.  
  39.         ; size
  40.         adc     dl, cl
  41.         adc     dh, ch
  42.  
  43.         adc     edx, 0
  44.  
  45. ;---------------------
  46. ; Real header and data
  47.  
  48.         push    esi
  49.         call    checksum_1
  50.         call    checksum_2
  51.         pop     esi
  52.  
  53. }       ; returns in dx only
  54.  
  55.  
  56.  
  57.  
  58. macro   TCP_sendseqinit ptr {
  59.  
  60.         push    edi                     ;;;; i dont like this static use of edi
  61.         mov     edi, [ptr + TCP_SOCKET.ISS]
  62.         mov     [ptr + TCP_SOCKET.SND_UP], edi
  63.         mov     [ptr + TCP_SOCKET.SND_MAX], edi
  64.         mov     [ptr + TCP_SOCKET.SND_NXT], edi
  65.         mov     [ptr + TCP_SOCKET.SND_UNA], edi
  66.         pop     edi
  67.  
  68. }
  69.  
  70.  
  71.  
  72. macro   TCP_rcvseqinit ptr {
  73.  
  74.         push    edi
  75.         mov     edi, [ptr + TCP_SOCKET.IRS]
  76.         inc     edi
  77.         mov     [ptr + TCP_SOCKET.RCV_NXT], edi
  78.         mov     [ptr + TCP_SOCKET.RCV_ADV], edi
  79.         pop     edi
  80.  
  81. }
  82.  
  83.  
  84.  
  85. macro   TCP_init_socket socket {
  86.  
  87.         mov     [socket + TCP_SOCKET.t_maxseg], TCP_mss_default
  88.         mov     [socket + TCP_SOCKET.t_flags], 0                ; we could also request scale and timestamp
  89.  
  90.         mov     [socket + TCP_SOCKET.t_srtt], TCP_time_srtt_default
  91.         mov     [socket + TCP_SOCKET.t_rttvar], TCP_time_rtt_default * 4
  92.         mov     [socket + TCP_SOCKET.t_rttmin], TCP_time_re_min
  93. ;;; TODO: TCP_time_rangeset
  94.  
  95.         mov     [socket + TCP_SOCKET.SND_CWND], TCP_max_win shl TCP_max_winshift
  96.         mov     [socket + TCP_SOCKET.SND_SSTHRESH], TCP_max_win shl TCP_max_winshift
  97.  
  98.  
  99. }
  100.  
  101.  
  102. ;---------------------------
  103. ;
  104. ; TCP_pull_out_of_band
  105. ;
  106. ; IN:  eax =
  107. ;      ebx = socket ptr
  108. ;      edx = tcp packet ptr
  109. ;
  110. ; OUT: /
  111. ;
  112. ;---------------------------
  113.  
  114. align 4
  115. TCP_pull_out_of_band:
  116.  
  117.         DEBUGF  1,"TCP_pull_out_of_band\n"
  118.  
  119.         ;;;; 1282-1305
  120.  
  121.         ret
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130. ;-------------------------
  131. ;
  132. ; TCP_drop
  133. ;
  134. ;  IN:  eax = socket ptr
  135. ;       ebx = error number
  136. ;
  137. ;  OUT: eax = socket ptr
  138. ;
  139. ;-------------------------
  140. align 4
  141. TCP_drop:
  142.  
  143.         DEBUGF  1,"TCP_drop: %x\n", eax
  144.  
  145.         cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
  146.         jb      .no_syn_received
  147.  
  148.         mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
  149.  
  150.         call    TCP_output
  151.  
  152. ;;; TODO: update stats
  153.  
  154.         jmp     TCP_close
  155.  
  156.   .no_syn_received:
  157.  
  158. ;;; TODO: update stats
  159.  
  160. ;;; TODO: check if error code is "Connection timed out' and handle accordingly
  161.  
  162.         mov     [eax + SOCKET.errorcode], ebx
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. ;-------------------------
  172. ;
  173. ; TCP_close
  174. ;
  175. ;  IN:  eax = socket ptr
  176. ;  OUT: eax = socket ptr
  177. ;
  178. ;-------------------------
  179. align 4
  180. TCP_close:
  181.  
  182.         DEBUGF  1,"TCP_close: %x\n", eax
  183.  
  184. ;;; TODO: update RTT and mean deviation
  185. ;;; TODO: update slow start threshold
  186.  
  187.         call    SOCKET_is_disconnected
  188.  
  189.         ret
  190.  
  191.  
  192.  
  193. ;-------------------------
  194. ;
  195. ; TCP_disconnect
  196. ;
  197. ;  IN:  eax = socket ptr
  198. ;  OUT: eax = socket ptr
  199. ;
  200. ;-------------------------
  201. align 4
  202. TCP_disconnect:
  203.  
  204.         DEBUGF  1,"TCP_disconnect: %x\n", eax
  205.  
  206.         cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
  207.         jb      TCP_close
  208.  
  209.  
  210. ; TODO: implement LINGER ?
  211.  
  212.         call    SOCKET_is_disconnecting
  213.         call    TCP_usrclosed
  214.         call    TCP_output
  215.  
  216.         ret
  217.  
  218.  
  219.  
  220. ;-------------------------
  221. ;
  222. ; TCP_usrclose
  223. ;
  224. ;  IN:  eax = socket ptr
  225. ;
  226. ;-------------------------
  227. align 4
  228. TCP_usrclosed:
  229.  
  230.         DEBUGF  1,"TCP_usrclosed: %x\n", eax
  231.  
  232.         push    ebx
  233.         mov     ebx, [eax + TCP_SOCKET.t_state]
  234.         mov     ebx, dword [.switch + ebx*4]
  235.         jmp     ebx
  236.  
  237.   .switch:
  238.  
  239.         dd      .close                  ; TCPS_CLOSED
  240.         dd      .close                  ; TCPS_LISTEN
  241.         dd      .close                  ; TCPS_SYN_SENT
  242.         dd      .wait1                  ; TCPS_SYN_RECEIVED
  243.         dd      .wait1                  ; TCPS_ESTABLISHED
  244.         dd      .last_ack               ; TCPS_CLOSE_WAIT
  245.         dd      .ret                    ; TCPS_FIN_WAIT_1
  246.         dd      .ret                    ; TCPS_CLOSING
  247.         dd      .ret                    ; TCPS_LAST_ACK
  248.         dd      .disc                   ; TCPS_FIN_WAIT_2
  249.         dd      .disc                   ; TCPS_TIMED_WAIT
  250.  
  251.  
  252.   .close:
  253.         pop     ebx
  254.         mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
  255.         call    TCP_close
  256.         ret
  257.  
  258.   .wait1:
  259.         pop     ebx
  260.         mov     [eax + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
  261.         ret
  262.  
  263.   .last_ack:
  264.         pop     ebx
  265.         mov     [eax + TCP_SOCKET.t_state], TCPS_LAST_ACK
  266.         ret
  267.  
  268.   .disc:
  269.         call    SOCKET_is_disconnected
  270.   .ret:
  271.         pop     ebx
  272.         ret
  273.  
  274.  
  275. ;-------------------------
  276. ;
  277. ; TCP_outflags
  278. ;
  279. ;  IN:  eax = socket ptr
  280. ;
  281. ;  OUT: edx = flags
  282. ;
  283. ;-------------------------
  284. align 4
  285. TCP_outflags:
  286.  
  287.         mov     edx, [eax + TCP_SOCKET.t_state]
  288.         movzx   edx, byte [edx + .flaglist]
  289.  
  290.         DEBUGF  1,"TCP_outflags: socket=%x flags=%x\n", eax, dl
  291.  
  292.         ret
  293.  
  294.   .flaglist:
  295.  
  296.         db      TH_RST + TH_ACK         ; TCPS_CLOSED
  297.         db      0                       ; TCPS_LISTEN
  298.         db      TH_SYN                  ; TCPS_SYN_SENT
  299.         db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
  300.         db               TH_ACK         ; TCPS_ESTABLISHED
  301.         db               TH_ACK         ; TCPS_CLOSE_WAIT
  302.         db      TH_FIN + TH_ACK         ; TCPS_FIN_WAIT_1
  303.         db      TH_FIN + TH_ACK         ; TCPS_CLOSING
  304.         db      TH_FIN + TH_ACK         ; TCPS_LAST_ACK
  305.         db               TH_ACK         ; TCPS_FIN_WAIT_2
  306.         db               TH_ACK         ; TCPS_TIMED_WAIT
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313. ;---------------------------------------
  314. ;
  315. ; The fast way to send an ACK/RST/keepalive segment
  316. ;
  317. ; TCP_respond_socket:
  318. ;
  319. ;  IN:  ebx = socket ptr
  320. ;        cl = flags
  321. ;
  322. ;--------------------------------------
  323. align 4
  324. TCP_respond_socket:
  325.  
  326.         DEBUGF  1,"TCP_respond_socket: socket=%x flags=%x\n", ebx, cl
  327.  
  328. ;---------------------
  329. ; Create the IP packet
  330.  
  331.         push    cx ebx
  332.         mov     eax, [ebx + IP_SOCKET.RemoteIP]
  333.         mov     edx, [ebx + IP_SOCKET.LocalIP]
  334.         mov     ecx, sizeof.TCP_header
  335.         mov     di, IP_PROTO_TCP shl 8 + 128
  336.         call    IPv4_output
  337.         test    edi, edi
  338.         jz      .error
  339.         pop     esi cx
  340.         push    edx eax
  341.  
  342. ;-----------------------------------------------
  343. ; Fill in the TCP header by using the socket ptr
  344.  
  345.         mov     ax, [esi + TCP_SOCKET.LocalPort]
  346.         rol     ax, 8
  347.         stosw
  348.         mov     ax, [esi + TCP_SOCKET.RemotePort]
  349.         rol     ax, 8
  350.         stosw
  351.         mov     eax, [esi + TCP_SOCKET.SND_NXT]
  352.         bswap   eax
  353.         stosd
  354.         mov     eax, [esi + TCP_SOCKET.RCV_NXT]
  355.         bswap   eax
  356.         stosd
  357.         mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
  358.         stosb
  359.         mov     al, cl
  360.         stosb
  361. ;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
  362. ;        rol     ax, 8
  363.         mov     ax, 0x00a0      ;;;;;;; FIXME
  364.         stosw                   ; window
  365.         xor     eax, eax
  366.         stosd                   ; checksum + urgentpointer
  367.  
  368. ;---------------------
  369. ; Fill in the checksum
  370.  
  371.   .checksum:
  372.         sub     edi, sizeof.TCP_header
  373.         mov     ecx, sizeof.TCP_header
  374.         xchg    esi, edi
  375.         TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
  376.         mov     [esi+TCP_header.Checksum], dx
  377.  
  378. ;--------------------
  379. ; And send the segment
  380.  
  381.         call    [ebx + NET_DEVICE.transmit]
  382.         ret
  383.  
  384.   .error:
  385.         DEBUGF  1,"TCP_respond_socket: failed\n"
  386.         add     esp, 2 + 4
  387.  
  388.         ret
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397. ;-------------------------
  398. ; TCP_respond.segment:
  399. ;
  400. ;  IN:  edx = segment ptr (a previously received segment)
  401. ;       edi = ptr to dest and src IPv4 addresses
  402. ;        cl = flags
  403.  
  404. align 4
  405. TCP_respond_segment:
  406.  
  407.         DEBUGF  1,"TCP_respond_segment: frame=%x flags=%c\n", edx, cl
  408.  
  409. ;---------------------
  410. ; Create the IP packet
  411.  
  412.         push    cx edx
  413.         mov     ebx, [edi + 4]
  414.         mov     eax, [edi]
  415.         mov     ecx, sizeof.TCP_header
  416.         mov     di , IP_PROTO_TCP shl 8 + 128
  417.         call    IPv4_output
  418.         jz      .error
  419.         pop     esi cx
  420.  
  421.         push    edx eax
  422.  
  423. ;---------------------------------------------------
  424. ; Fill in the TCP header by using a received segment
  425.  
  426.         mov     ax, [esi + TCP_header.DestinationPort]
  427.         rol     ax, 8
  428.         stosw
  429.         mov     ax, [esi + TCP_header.SourcePort]
  430.         rol     ax, 8
  431.         stosw
  432.         mov     eax, [esi + TCP_header.AckNumber]
  433.         bswap   eax
  434.         stosd
  435.         xor     eax, eax
  436.         stosd
  437.         mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header)
  438.         stosb
  439.         mov     al, cl
  440.         stosb
  441.         mov     ax, 1280
  442.         rol     ax, 8
  443.         stosw                   ; window
  444.         xor     eax, eax
  445.         stosd                   ; checksum + urgentpointer
  446.  
  447. ;---------------------
  448. ; Fill in the checksum
  449.  
  450.   .checksum:
  451.         lea     esi, [edi - sizeof.TCP_header]
  452.         mov     ecx, sizeof.TCP_header
  453.         TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
  454.                      (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
  455.         mov     [esi+TCP_header.Checksum], dx
  456.  
  457. ;--------------------
  458. ; And send the segment
  459.  
  460.         call    [ebx + NET_DEVICE.transmit]
  461.         ret
  462.  
  463.   .error:
  464.         DEBUGF  1,"TCP_respond_segment: failed\n"
  465.         add     esp, 2+4
  466.  
  467.         ret
  468.  
  469.  
  470.  
  471. macro TCP_set_persist socket {
  472.  
  473. ;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
  474. ;int tt;
  475. ;
  476. ;tp->t_flags &= ~TF_PREVVALID;
  477. ;
  478. ;if (tcp_timer_active(tp, TT_REXMT))
  479. ;        panic("tcp_setpersist: retransmit pending");
  480. ;
  481. ;; Start/restart persistance timer.
  482. ;
  483. ;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX);
  484. ;tcp_timer_activate(tp, TT_PERSIST, tt);
  485. ;
  486. ;if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
  487. ;        tp->t_rxtshift++;
  488.  
  489. }
  490.  
  491. ; eax = rtt
  492. ; ebx = socket ptr
  493.  
  494. align 4
  495. TCP_xmit_timer:
  496.  
  497. ;TODO: update srtt and rttvar
  498.  
  499. ret
  500.