Subversion Repositories Kolibri OS

Rev

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

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