Subversion Repositories Kolibri OS

Rev

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

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