Subversion Repositories Kolibri OS

Rev

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

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