Subversion Repositories Kolibri OS

Rev

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

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