Subversion Repositories Kolibri OS

Rev

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

Rev 3556 Rev 3600
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
        ret
305
        ret
306
 
306
 
307
  .error:
307
  .error:
308
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: failed\n"
308
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: failed\n"
309
        add     esp, 2 + 4
309
        add     esp, 2 + 4
310
 
310
 
311
        ret
311
        ret
312
 
312
 
313
 
313
 
314
 
314
 
315
 
315
 
316
 
316
 
317
 
317
 
318
 
318
 
319
 
319
 
320
;-------------------------
320
;-------------------------
321
; TCP_respond_segment:
321
; TCP_respond_segment:
322
;
322
;
323
;  IN:  edx = segment ptr (a previously received segment)
323
;  IN:  edx = segment ptr (a previously received segment)
324
;       edi = ptr to dest and src IPv4 addresses
324
;       edi = ptr to dest and src IPv4 addresses
325
;        cl = flags
325
;        cl = flags
326
 
326
 
327
align 4
327
align 4
328
TCP_respond_segment:
328
TCP_respond_segment:
329
 
329
 
330
        DEBUGF  DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl
330
        DEBUGF  DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl
331
 
331
 
332
;---------------------
332
;---------------------
333
; Create the IP packet
333
; Create the IP packet
334
 
334
 
335
        push    cx edx
335
        push    cx edx
336
        mov     ebx, [edi + 4]
336
        mov     ebx, [edi + 4]
337
        mov     eax, [edi]
337
        mov     eax, [edi]
338
        mov     ecx, sizeof.TCP_header
338
        mov     ecx, sizeof.TCP_header
339
        mov     di, IP_PROTO_TCP shl 8 + 128
339
        mov     di, IP_PROTO_TCP shl 8 + 128
340
        call    IPv4_output
340
        call    IPv4_output
341
        jz      .error
341
        jz      .error
342
        pop     esi cx
342
        pop     esi cx
343
 
343
 
344
        push    edx eax
344
        push    edx eax
345
 
345
 
346
;---------------------------------------------------
346
;---------------------------------------------------
347
; Fill in the TCP header by using a received segment
347
; Fill in the TCP header by using a received segment
348
 
348
 
349
        mov     ax, [esi + TCP_header.DestinationPort]
349
        mov     ax, [esi + TCP_header.DestinationPort]
350
        stosw
350
        stosw
351
        mov     ax, [esi + TCP_header.SourcePort]
351
        mov     ax, [esi + TCP_header.SourcePort]
352
        stosw
352
        stosw
353
        mov     eax, [esi + TCP_header.AckNumber]
353
        mov     eax, [esi + TCP_header.AckNumber]
354
        bswap   eax
354
        bswap   eax
355
        stosd
355
        stosd
356
        xor     eax, eax
356
        xor     eax, eax
357
        stosd
357
        stosd
358
        mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header/4 shl 4)
358
        mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header/4 shl 4)
359
        stosb
359
        stosb
360
        mov     al, cl
360
        mov     al, cl
361
        stosb
361
        stosb
362
        mov     ax, 1280
362
        mov     ax, 1280
363
        rol     ax, 8
363
        rol     ax, 8
364
        stosw                   ; window
364
        stosw                   ; window
365
        xor     eax, eax
365
        xor     eax, eax
366
        stosd                   ; checksum + urgentpointer
366
        stosd                   ; checksum + urgentpointer
367
 
367
 
368
;---------------------
368
;---------------------
369
; Fill in the checksum
369
; Fill in the checksum
370
 
370
 
371
        lea     esi, [edi - sizeof.TCP_header]
371
        lea     esi, [edi - sizeof.TCP_header]
372
        mov     ecx, sizeof.TCP_header
372
        mov     ecx, sizeof.TCP_header
373
        TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
373
        TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
374
                     (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
374
                     (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
375
        mov     [esi + TCP_header.Checksum], dx
375
        mov     [esi + TCP_header.Checksum], dx
376
 
376
 
377
;--------------------
377
;--------------------
378
; And send the segment
378
; And send the segment
379
 
379
 
380
        call    [ebx + NET_DEVICE.transmit]
380
        call    [ebx + NET_DEVICE.transmit]
381
        ret
381
        ret
382
 
382
 
383
  .error:
383
  .error:
384
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: failed\n"
384
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: failed\n"
385
        add     esp, 2+4
385
        add     esp, 2+4
386
 
386
 
387
        ret
387
        ret
388
 
388
 
389
 
389
 
390
macro   TCPT_RANGESET   timer, value, min, max {
390
macro   TCPT_RANGESET   timer, value, min, max {
391
 
391
 
392
local   .min
392
local   .min
393
local   .max
393
local   .max
394
local   .done
394
local   .done
395
 
395
 
396
        cmp     value, min
396
        cmp     value, min
397
        jb      .min
397
        jb      .min
398
        cmp     value, max
398
        cmp     value, max
399
        ja      .max
399
        ja      .max
400
 
400
 
401
        mov     timer, value
401
        mov     timer, value
402
        jmp     .done
402
        jmp     .done
403
 
403
 
404
  .min:
404
  .min:
405
        mov     timer, value
405
        mov     timer, value
406
        jmp     .done
406
        jmp     .done
407
 
407
 
408
  .max:
408
  .max:
409
        mov     timer, value
409
        mov     timer, value
410
        jmp     .done
410
        jmp     .done
411
 
411
 
412
  .done:
412
  .done:
413
}
413
}
414
 
414
 
415
 
415
 
416
align 4
416
align 4
417
TCP_set_persist:
417
TCP_set_persist:
418
 
418
 
419
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_set_persist\n"
419
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_set_persist\n"
420
 
420
 
421
; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive
421
; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive
422
 
422
 
423
        cmp     [eax + TCP_SOCKET.timer_retransmission], 0
423
        test    [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
424
        ja      @f
424
        jnz     .exit
425
 
425
 
426
; calculate RTO
426
; calculate RTO
427
        push    ebx
427
        push    ebx
428
        mov     ebx, [eax + TCP_SOCKET.t_srtt]
428
        mov     ebx, [eax + TCP_SOCKET.t_srtt]
429
        shr     ebx, 2
429
        shr     ebx, 2
430
        add     ebx, [eax + TCP_SOCKET.t_rttvar]
430
        add     ebx, [eax + TCP_SOCKET.t_rttvar]
431
        shr     ebx, 1
431
        shr     ebx, 1
432
 
432
 
433
        mov     cl, [eax + TCP_SOCKET.t_rxtshift]
433
        mov     cl, [eax + TCP_SOCKET.t_rxtshift]
434
        shl     ebx, cl
434
        shl     ebx, cl
435
 
435
 
436
; Start/restart persistance timer.
436
; Start/restart persistance timer.
437
 
437
 
438
        TCPT_RANGESET   [eax + TCP_SOCKET.timer_persist], ebx, TCP_time_pers_min, TCP_time_pers_max
438
        TCPT_RANGESET   [eax + TCP_SOCKET.timer_persist], ebx, TCP_time_pers_min, TCP_time_pers_max
439
 
-
 
-
 
439
        or      [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
440
        pop     ebx
440
        pop     ebx
441
 
441
 
442
        cmp     [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift
442
        cmp     [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift
443
        jae     @f
443
        jae     @f
444
        inc     [eax + TCP_SOCKET.t_rxtshift]
444
        inc     [eax + TCP_SOCKET.t_rxtshift]
445
      @@:
445
      @@:
-
 
446
  .exit:
446
 
447
 
447
        ret
448
        ret
448
 
449
 
449
 
450
 
450
 
451
 
451
; eax = rtt
452
; eax = rtt
452
; ebx = socket ptr
453
; ebx = socket ptr
453
 
454
 
454
align 4
455
align 4
455
TCP_xmit_timer:
456
TCP_xmit_timer:
456
 
457
 
457
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
458
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
458
 
459
 
459
;TODO: update stats
460
;TODO: update stats
460
 
461
 
461
        cmp     [ebx + TCP_SOCKET.t_rtt], 0
462
        cmp     [ebx + TCP_SOCKET.t_rtt], 0
462
        je      .no_rtt_yet
463
        je      .no_rtt_yet
463
 
464
 
464
; srtt is stored as a fixed point with 3 bits after the binary point.
465
; srtt is stored as a fixed point with 3 bits after the binary point.
465
; The following magic is equivalent of the smoothing algorithm in rfc793 with an alpha of .875
466
; The following magic is equivalent of the smoothing algorithm in rfc793 with an alpha of .875
466
; (srtt = rtt/8 + srtt*7/8 in fixed point)
467
; (srtt = rtt/8 + srtt*7/8 in fixed point)
467
; Adjust rtt to origin 0.
468
; Adjust rtt to origin 0.
468
 
469
 
469
        push    ecx
470
        push    ecx
470
        mov     ecx, [ebx + TCP_SOCKET.t_srtt]
471
        mov     ecx, [ebx + TCP_SOCKET.t_srtt]
471
        shr     ecx, TCP_RTT_SHIFT
472
        shr     ecx, TCP_RTT_SHIFT
472
        sub     eax, ecx
473
        sub     eax, ecx
473
        dec     eax
474
        dec     eax
474
        pop     ecx
475
        pop     ecx
475
 
476
 
476
        add     [ebx + TCP_SOCKET.t_srtt], eax
477
        add     [ebx + TCP_SOCKET.t_srtt], eax
477
        ja      @f
478
        ja      @f
478
        mov     [ebx + TCP_SOCKET.t_srtt], 1
479
        mov     [ebx + TCP_SOCKET.t_srtt], 1
479
  @@:
480
  @@:
480
 
481
 
481
; We accumulate a smoothed rtt variance (actually, a smoothed mean difference),
482
; We accumulate a smoothed rtt variance (actually, a smoothed mean difference),
482
; then set the retransmit timer to smoothed rtt + 4 times the smoothed variance.
483
; then set the retransmit timer to smoothed rtt + 4 times the smoothed variance.
483
; rttvar is stored as fixed point with 2 bits after the binary point.
484
; rttvar is stored as fixed point with 2 bits after the binary point.
484
; The following is equivalent to rfc793 smoothing with an alpha of .75
485
; The following is equivalent to rfc793 smoothing with an alpha of .75
485
; (rttvar = rttvar*3/4 + delta/4) (delta = eax)
486
; (rttvar = rttvar*3/4 + delta/4) (delta = eax)
486
 
487
 
487
; get abs(eax)
488
; get abs(eax)
488
        push    edx
489
        push    edx
489
        cdq
490
        cdq
490
        xor     eax, edx
491
        xor     eax, edx
491
        sub     eax, edx
492
        sub     eax, edx
492
 
493
 
493
        mov     edx, [ebx + TCP_SOCKET.t_rttvar]
494
        mov     edx, [ebx + TCP_SOCKET.t_rttvar]
494
        shr     edx, TCP_RTTVAR_SHIFT
495
        shr     edx, TCP_RTTVAR_SHIFT
495
        sub     eax, edx
496
        sub     eax, edx
496
        pop     edx
497
        pop     edx
497
 
498
 
498
        add     [ebx + TCP_SOCKET.t_rttvar], eax
499
        add     [ebx + TCP_SOCKET.t_rttvar], eax
499
        ja      @f
500
        ja      @f
500
        mov     [ebx + TCP_SOCKET.t_rttvar], 1
501
        mov     [ebx + TCP_SOCKET.t_rttvar], 1
501
  @@:
502
  @@:
502
        ret
503
        ret
503
 
504
 
504
 
505
 
505
  .no_rtt_yet:
506
  .no_rtt_yet:
506
 
507
 
507
        push    ecx
508
        push    ecx
508
        mov     ecx, eax
509
        mov     ecx, eax
509
        shl     ecx, TCP_RTT_SHIFT
510
        shl     ecx, TCP_RTT_SHIFT
510
        mov     [ebx + TCP_SOCKET.t_srtt], ecx
511
        mov     [ebx + TCP_SOCKET.t_srtt], ecx
511
 
512
 
512
        shl     eax, TCP_RTTVAR_SHIFT - 1
513
        shl     eax, TCP_RTTVAR_SHIFT - 1
513
        mov     [ebx + TCP_SOCKET.t_rttvar], eax
514
        mov     [ebx + TCP_SOCKET.t_rttvar], eax
514
        pop     ecx
515
        pop     ecx
515
 
516
 
516
        ret
517
        ret
517
 
518
 
518
 
519
 
519
 
520
 
520
 
521
 
521
; eax = max segment size
522
; eax = max segment size
522
; ebx = socket ptr
523
; ebx = socket ptr
523
align 4
524
align 4
524
TCP_mss:
525
TCP_mss:
525
 
526
 
526
        cmp     eax, 1420                               ; FIXME
527
        cmp     eax, 1420                               ; FIXME
527
        jbe     @f
528
        jbe     @f
528
        mov     eax, 1420
529
        mov     eax, 1420
529
  @@:
530
  @@:
530
        mov     [ebx + TCP_SOCKET.t_maxseg], eax
531
        mov     [ebx + TCP_SOCKET.t_maxseg], eax
531
 
532
 
532
 
533
 
533
        ret
534
        ret
534
 
535
 
535
 
536
 
536
 
537
 
537
 
538
 
538
; ebx = socket ptr
539
; ebx = socket ptr
539
; edx = segment ptr
540
; edx = segment ptr
540
align 4
541
align 4
541
TCP_reassemble:
542
TCP_reassemble:
542
 
543
 
543
 
544
 
544
 
545
 
545
        ret
546
        ret