Subversion Repositories Kolibri OS

Rev

Rev 5842 | Rev 6011 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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