Subversion Repositories Kolibri OS

Rev

Rev 2390 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1763 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2362 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
1763 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
9
;;                                                                 ;;
10
;;    Based on the code of 4.4BSD                                  ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1733 hidnplayr 16
 
1763 hidnplayr 17
$Revision: 2600 $
1733 hidnplayr 18
 
2390 hidnplayr 19
macro   TCP_checksum IP1, IP2 {
1733 hidnplayr 20
 
21
;-------------
22
; Pseudoheader
23
 
2390 hidnplayr 24
        ; protocol type
25
        mov     edx, IP_PROTO_TCP
1733 hidnplayr 26
 
2390 hidnplayr 27
        ; source address
28
        add     dl, byte [IP1+1]
29
        adc     dh, byte [IP1+0]
30
        adc     dl, byte [IP1+3]
31
        adc     dh, byte [IP1+2]
1733 hidnplayr 32
 
2390 hidnplayr 33
        ; destination address
34
        adc     dl, byte [IP2+1]
35
        adc     dh, byte [IP2+0]
36
        adc     dl, byte [IP2+3]
37
        adc     dh, byte [IP2+2]
1733 hidnplayr 38
 
2390 hidnplayr 39
        ; size
40
        adc     dl, cl
41
        adc     dh, ch
1733 hidnplayr 42
 
2390 hidnplayr 43
        adc     edx, 0
44
 
1733 hidnplayr 45
;---------------------
46
; Real header and data
47
 
2390 hidnplayr 48
        push    esi
49
        call    checksum_1
50
        call    checksum_2
51
        pop     esi
1733 hidnplayr 52
 
2390 hidnplayr 53
}       ; returns in dx only
1733 hidnplayr 54
 
55
 
56
 
57
 
2390 hidnplayr 58
macro   TCP_sendseqinit ptr {
1733 hidnplayr 59
 
2390 hidnplayr 60
        push    edi                     ;;;; i dont like this static use of edi
61
        mov     edi, [ptr + TCP_SOCKET.ISS]
62
        mov     [ptr + TCP_SOCKET.SND_UP], edi
63
        mov     [ptr + TCP_SOCKET.SND_MAX], edi
64
        mov     [ptr + TCP_SOCKET.SND_NXT], edi
65
        mov     [ptr + TCP_SOCKET.SND_UNA], edi
66
        pop     edi
1733 hidnplayr 67
 
68
}
69
 
70
 
71
 
2390 hidnplayr 72
macro   TCP_rcvseqinit ptr {
1733 hidnplayr 73
 
2390 hidnplayr 74
        push    edi
75
        mov     edi, [ptr + TCP_SOCKET.IRS]
76
        inc     edi
77
        mov     [ptr + TCP_SOCKET.RCV_NXT], edi
78
        mov     [ptr + TCP_SOCKET.RCV_ADV], edi
79
        pop     edi
1733 hidnplayr 80
 
81
}
82
 
83
 
84
 
85
 
86
 
87
 
88
 
89
 
90
 
91
 
92
;---------------------------
93
;
94
; TCP_pull_out_of_band
95
;
96
; IN:  eax =
97
;      ebx = socket ptr
98
;      edx = tcp packet ptr
99
;
100
; OUT: /
101
;
102
;---------------------------
103
 
104
align 4
105
TCP_pull_out_of_band:
106
 
2390 hidnplayr 107
        DEBUGF  1,"TCP_pull_out_of_band\n"
1733 hidnplayr 108
 
2390 hidnplayr 109
        ;;;; 1282-1305
1733 hidnplayr 110
 
2390 hidnplayr 111
        ret
1733 hidnplayr 112
 
113
 
114
 
115
 
116
 
117
 
118
 
119
 
120
;-------------------------
121
;
122
; TCP_drop
123
;
124
;  IN:  eax = socket ptr
125
;       ebx = error number
126
;
127
;  OUT: eax = socket ptr
128
;
129
;-------------------------
130
align 4
131
TCP_drop:
132
 
2390 hidnplayr 133
        DEBUGF  1,"TCP_drop\n"
1733 hidnplayr 134
 
2390 hidnplayr 135
        cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
136
        jb      .no_syn_received
1733 hidnplayr 137
 
2390 hidnplayr 138
        mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
1733 hidnplayr 139
 
2390 hidnplayr 140
        call    TCP_output
1733 hidnplayr 141
 
142
;;; TODO: update stats
143
 
2390 hidnplayr 144
        jmp     TCP_close
1733 hidnplayr 145
 
146
  .no_syn_received:
147
 
148
;;; TODO: update stats
149
 
150
;;; TODO: check if error code is "Connection timed out' and handle accordingly
151
 
2390 hidnplayr 152
        mov     [eax + SOCKET.errorcode], ebx
1733 hidnplayr 153
 
154
 
155
 
156
 
157
 
158
 
159
 
160
 
161
;-------------------------
162
;
163
; TCP_close
164
;
165
;  IN:  eax = socket ptr
166
;  OUT: eax = socket ptr
167
;
168
;-------------------------
169
align 4
170
TCP_close:
171
 
2390 hidnplayr 172
        DEBUGF  1,"TCP_close\n"
1733 hidnplayr 173
 
174
;;; TODO: update RTT and mean deviation
175
;;; TODO: update slow start threshold
176
;;; TODO: release connection resources
177
 
2390 hidnplayr 178
        call    SOCKET_is_disconnected
1733 hidnplayr 179
 
2390 hidnplayr 180
        ret
1733 hidnplayr 181
 
182
 
183
 
184
 
185
 
186
 
187
 
188
 
189
 
190
 
191
;-------------------------
192
;
193
; TCP_outflags
194
;
195
;  IN:  eax = socket ptr
196
;
197
;  OUT: edx = flags
198
;
199
;-------------------------
200
align 4
201
TCP_outflags:
202
 
2390 hidnplayr 203
        mov     edx, [eax + TCP_SOCKET.t_state]
204
        movzx   edx, byte [edx + .flaglist]
1733 hidnplayr 205
 
2390 hidnplayr 206
        DEBUGF  1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
1733 hidnplayr 207
 
2390 hidnplayr 208
        ret
1733 hidnplayr 209
 
210
  .flaglist:
211
 
2390 hidnplayr 212
        db      TH_RST + TH_ACK         ; TCPS_CLOSED
213
        db      0                       ; TCPS_LISTEN
214
        db      TH_SYN                  ; TCPS_SYN_SENT
215
        db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
216
        db               TH_ACK         ; TCPS_ESTABLISHED
217
        db               TH_ACK         ; TCPS_CLOSE_WAIT
218
        db      TH_SYN + TH_ACK         ; TCPS_FIN_WAIT_1
219
        db      TH_SYN + TH_ACK         ; TCPS_CLOSING
220
        db      TH_SYN + TH_ACK         ; TCPS_LAST_ACK
221
        db               TH_ACK         ; TCPS_FIN_WAIT_2
222
        db               TH_ACK         ; TCPS_TIMED_WAIT
1733 hidnplayr 223
 
224
 
225
 
226
 
227
 
228
 
229
;---------------------------------------
230
;
1830 hidnplayr 231
; The fast way to send an ACK/RST/keepalive segment
1733 hidnplayr 232
;
233
; TCP_respond_socket:
234
;
235
;  IN:  ebx = socket ptr
236
;        cl = flags
237
;
238
;--------------------------------------
239
align 4
240
TCP_respond_socket:
241
 
2390 hidnplayr 242
        DEBUGF  1,"TCP_respond_socket\n"
1733 hidnplayr 243
 
244
;---------------------
245
; Create the IP packet
246
 
2390 hidnplayr 247
        push    cx ebx
248
        mov     eax, [ebx + IP_SOCKET.RemoteIP]
249
        mov     ebx, [ebx + IP_SOCKET.LocalIP]
250
        mov     ecx, sizeof.TCP_header
251
        mov     di , IP_PROTO_TCP shl 8 + 128
252
        call    IPv4_output
253
        test    edi, edi
254
        jz      .error
255
        pop     esi cx
256
        push    edx eax
1733 hidnplayr 257
 
258
;-----------------------------------------------
259
; Fill in the TCP header by using the socket ptr
260
 
2390 hidnplayr 261
        mov     ax, [esi + TCP_SOCKET.LocalPort]
262
        rol     ax, 8
263
        stosw
264
        mov     ax, [esi + TCP_SOCKET.RemotePort]
265
        rol     ax, 8
266
        stosw
267
        mov     eax, [esi + TCP_SOCKET.SND_NXT]
268
        bswap   eax
269
        stosd
270
        mov     eax, [esi + TCP_SOCKET.RCV_NXT]
271
        bswap   eax
272
        stosd
273
        mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
274
        stosb
275
        mov     al, cl
276
        stosb
1830 hidnplayr 277
;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
278
;        rol     ax, 8
2390 hidnplayr 279
        mov     ax, 0x00a0      ;;;;;;; FIXME
280
        stosw                   ; window
281
        xor     eax, eax
282
        stosd                   ; checksum + urgentpointer
1733 hidnplayr 283
 
284
;---------------------
285
; Fill in the checksum
286
 
287
  .checksum:
2390 hidnplayr 288
        sub     edi, sizeof.TCP_header
289
        mov     ecx, sizeof.TCP_header
290
        xchg    esi, edi
291
        TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
292
        mov     [esi+TCP_header.Checksum], dx
1733 hidnplayr 293
 
294
;--------------------
295
; And send the segment
296
 
2390 hidnplayr 297
        call    [ebx + NET_DEVICE.transmit]
298
        ret
1733 hidnplayr 299
 
300
  .error:
2390 hidnplayr 301
        DEBUGF  1,"TCP_respond failed\n"
302
        add     esp, 2+4
1733 hidnplayr 303
 
2390 hidnplayr 304
        ret
1733 hidnplayr 305
 
306
 
307
 
308
 
309
 
310
 
311
 
312
 
313
;-------------------------
314
; TCP_respond.segment:
315
;
2600 hidnplayr 316
;  IN:  edx = segment ptr (a previously received segment)
2308 hidnplayr 317
;       edi = ptr to dest and src IPv4 addresses
1733 hidnplayr 318
;        cl = flags
319
 
320
align 4
321
TCP_respond_segment:
322
 
2390 hidnplayr 323
        DEBUGF  1,"TCP_respond_segment\n"
1733 hidnplayr 324
 
325
;---------------------
326
; Create the IP packet
327
 
2600 hidnplayr 328
        push    cx edx
2390 hidnplayr 329
        mov     ebx, [edi + 4]
330
        mov     eax, [edi]
331
        mov     ecx, sizeof.TCP_header
332
        mov     di , IP_PROTO_TCP shl 8 + 128
333
        call    IPv4_output
334
        jz      .error
2600 hidnplayr 335
        pop     esi cx
1733 hidnplayr 336
 
2390 hidnplayr 337
        push    edx eax
1733 hidnplayr 338
 
339
;---------------------------------------------------
340
; Fill in the TCP header by using a received segment
341
 
2390 hidnplayr 342
        mov     ax, [esi + TCP_header.DestinationPort]
343
        rol     ax, 8
344
        stosw
345
        mov     ax, [esi + TCP_header.SourcePort]
346
        rol     ax, 8
347
        stosw
348
        mov     eax, [esi + TCP_header.AckNumber]
349
        bswap   eax
350
        stosd
351
        xor     eax, eax
352
        stosd
353
        mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header)
354
        stosb
355
        mov     al, cl
356
        stosb
357
        mov     ax, 1280
358
        rol     ax, 8
359
        stosw                   ; window
360
        xor     eax, eax
361
        stosd                   ; checksum + urgentpointer
1733 hidnplayr 362
 
363
;---------------------
364
; Fill in the checksum
365
 
366
  .checksum:
2390 hidnplayr 367
        lea     esi, [edi - sizeof.TCP_header]
368
        mov     ecx, sizeof.TCP_header
369
        TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
370
                     (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
371
        mov     [esi+TCP_header.Checksum], dx
1733 hidnplayr 372
 
373
;--------------------
374
; And send the segment
375
 
2390 hidnplayr 376
        call    [ebx + NET_DEVICE.transmit]
377
        ret
1733 hidnplayr 378
 
379
  .error:
2390 hidnplayr 380
        DEBUGF  1,"TCP_respond failed\n"
381
        add     esp, 2+4
1733 hidnplayr 382
 
2390 hidnplayr 383
        ret
2362 hidnplayr 384
 
385
 
386
 
387
macro TCP_set_persist socket {
388
 
389
;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
390
;int tt;
391
;
392
;tp->t_flags &= ~TF_PREVVALID;
393
;
394
;if (tcp_timer_active(tp, TT_REXMT))
395
;        panic("tcp_setpersist: retransmit pending");
396
;
397
;; Start/restart persistance timer.
398
;
399
;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX);
400
;tcp_timer_activate(tp, TT_PERSIST, tt);
401
;
402
;if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
403
;        tp->t_rxtshift++;
404
 
405
}