Subversion Repositories Kolibri OS

Rev

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

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