Subversion Repositories Kolibri OS

Rev

Rev 2600 | 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: 2612 $
  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\n"
  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\n"
  183.  
  184. ;;; TODO: update RTT and mean deviation
  185. ;;; TODO: update slow start threshold
  186. ;;; TODO: release connection resources
  187.  
  188.         call    SOCKET_is_disconnected
  189.  
  190.         ret
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. ;-------------------------
  202. ;
  203. ; TCP_outflags
  204. ;
  205. ;  IN:  eax = socket ptr
  206. ;
  207. ;  OUT: edx = flags
  208. ;
  209. ;-------------------------
  210. align 4
  211. TCP_outflags:
  212.  
  213.         mov     edx, [eax + TCP_SOCKET.t_state]
  214.         movzx   edx, byte [edx + .flaglist]
  215.  
  216.         DEBUGF  1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
  217.  
  218.         ret
  219.  
  220.   .flaglist:
  221.  
  222.         db      TH_RST + TH_ACK         ; TCPS_CLOSED
  223.         db      0                       ; TCPS_LISTEN
  224.         db      TH_SYN                  ; TCPS_SYN_SENT
  225.         db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
  226.         db               TH_ACK         ; TCPS_ESTABLISHED
  227.         db               TH_ACK         ; TCPS_CLOSE_WAIT
  228.         db      TH_SYN + TH_ACK         ; TCPS_FIN_WAIT_1
  229.         db      TH_SYN + TH_ACK         ; TCPS_CLOSING
  230.         db      TH_SYN + TH_ACK         ; TCPS_LAST_ACK
  231.         db               TH_ACK         ; TCPS_FIN_WAIT_2
  232.         db               TH_ACK         ; TCPS_TIMED_WAIT
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. ;---------------------------------------
  240. ;
  241. ; The fast way to send an ACK/RST/keepalive segment
  242. ;
  243. ; TCP_respond_socket:
  244. ;
  245. ;  IN:  ebx = socket ptr
  246. ;        cl = flags
  247. ;
  248. ;--------------------------------------
  249. align 4
  250. TCP_respond_socket:
  251.  
  252.         DEBUGF  1,"TCP_respond_socket\n"
  253.  
  254. ;---------------------
  255. ; Create the IP packet
  256.  
  257.         push    cx ebx
  258.         mov     eax, [ebx + IP_SOCKET.RemoteIP]
  259.         mov     ebx, [ebx + IP_SOCKET.LocalIP]
  260.         mov     ecx, sizeof.TCP_header
  261.         mov     di , IP_PROTO_TCP shl 8 + 128
  262.         call    IPv4_output
  263.         test    edi, edi
  264.         jz      .error
  265.         pop     esi cx
  266.         push    edx eax
  267.  
  268. ;-----------------------------------------------
  269. ; Fill in the TCP header by using the socket ptr
  270.  
  271.         mov     ax, [esi + TCP_SOCKET.LocalPort]
  272.         rol     ax, 8
  273.         stosw
  274.         mov     ax, [esi + TCP_SOCKET.RemotePort]
  275.         rol     ax, 8
  276.         stosw
  277.         mov     eax, [esi + TCP_SOCKET.SND_NXT]
  278.         bswap   eax
  279.         stosd
  280.         mov     eax, [esi + TCP_SOCKET.RCV_NXT]
  281.         bswap   eax
  282.         stosd
  283.         mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
  284.         stosb
  285.         mov     al, cl
  286.         stosb
  287. ;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
  288. ;        rol     ax, 8
  289.         mov     ax, 0x00a0      ;;;;;;; FIXME
  290.         stosw                   ; window
  291.         xor     eax, eax
  292.         stosd                   ; checksum + urgentpointer
  293.  
  294. ;---------------------
  295. ; Fill in the checksum
  296.  
  297.   .checksum:
  298.         sub     edi, sizeof.TCP_header
  299.         mov     ecx, sizeof.TCP_header
  300.         xchg    esi, edi
  301.         TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
  302.         mov     [esi+TCP_header.Checksum], dx
  303.  
  304. ;--------------------
  305. ; And send the segment
  306.  
  307.         call    [ebx + NET_DEVICE.transmit]
  308.         ret
  309.  
  310.   .error:
  311.         DEBUGF  1,"TCP_respond failed\n"
  312.         add     esp, 2+4
  313.  
  314.         ret
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323. ;-------------------------
  324. ; TCP_respond.segment:
  325. ;
  326. ;  IN:  edx = segment ptr (a previously received segment)
  327. ;       edi = ptr to dest and src IPv4 addresses
  328. ;        cl = flags
  329.  
  330. align 4
  331. TCP_respond_segment:
  332.  
  333.         DEBUGF  1,"TCP_respond_segment\n"
  334.  
  335. ;---------------------
  336. ; Create the IP packet
  337.  
  338.         push    cx edx
  339.         mov     ebx, [edi + 4]
  340.         mov     eax, [edi]
  341.         mov     ecx, sizeof.TCP_header
  342.         mov     di , IP_PROTO_TCP shl 8 + 128
  343.         call    IPv4_output
  344.         jz      .error
  345.         pop     esi cx
  346.  
  347.         push    edx eax
  348.  
  349. ;---------------------------------------------------
  350. ; Fill in the TCP header by using a received segment
  351.  
  352.         mov     ax, [esi + TCP_header.DestinationPort]
  353.         rol     ax, 8
  354.         stosw
  355.         mov     ax, [esi + TCP_header.SourcePort]
  356.         rol     ax, 8
  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)
  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.   .checksum:
  377.         lea     esi, [edi - sizeof.TCP_header]
  378.         mov     ecx, sizeof.TCP_header
  379.         TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
  380.                      (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
  381.         mov     [esi+TCP_header.Checksum], dx
  382.  
  383. ;--------------------
  384. ; And send the segment
  385.  
  386.         call    [ebx + NET_DEVICE.transmit]
  387.         ret
  388.  
  389.   .error:
  390.         DEBUGF  1,"TCP_respond failed\n"
  391.         add     esp, 2+4
  392.  
  393.         ret
  394.  
  395.  
  396.  
  397. macro TCP_set_persist socket {
  398.  
  399. ;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
  400. ;int tt;
  401. ;
  402. ;tp->t_flags &= ~TF_PREVVALID;
  403. ;
  404. ;if (tcp_timer_active(tp, TT_REXMT))
  405. ;        panic("tcp_setpersist: retransmit pending");
  406. ;
  407. ;; Start/restart persistance timer.
  408. ;
  409. ;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX);
  410. ;tcp_timer_activate(tp, TT_PERSIST, tt);
  411. ;
  412. ;if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
  413. ;        tp->t_rxtshift++;
  414.  
  415. }
  416.