Subversion Repositories Kolibri OS

Rev

Rev 2600 | 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: 2612 $
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
 
2612 hidnplayr 85
macro TCP_init_socket socket {
1733 hidnplayr 86
 
2612 hidnplayr 87
        mov     [socket + TCP_SOCKET.t_maxseg], TCP_mss_default
88
        mov     [socket + TCP_SOCKET.t_flags], 0                ; we could also request scale and timestamp
1733 hidnplayr 89
 
2612 hidnplayr 90
        mov     [socket + TCP_SOCKET.t_srtt], TCP_time_srtt_default
91
        mov     [socket + TCP_SOCKET.t_rttvar], TCP_time_rtt_default * 4
92
        mov     [socket + TCP_SOCKET.t_rttmin], TCP_time_re_min
93
;;; TODO: TCP_time_rangeset
1733 hidnplayr 94
 
2612 hidnplayr 95
        mov     [socket + TCP_SOCKET.SND_CWND], TCP_max_win shl TCP_max_winshift
96
        mov     [socket + TCP_SOCKET.SND_SSTHRESH], TCP_max_win shl TCP_max_winshift
1733 hidnplayr 97
 
98
 
2612 hidnplayr 99
}
1733 hidnplayr 100
 
101
 
102
;---------------------------
103
;
104
; TCP_pull_out_of_band
105
;
106
; IN:  eax =
107
;      ebx = socket ptr
108
;      edx = tcp packet ptr
109
;
110
; OUT: /
111
;
112
;---------------------------
113
 
114
align 4
115
TCP_pull_out_of_band:
116
 
2390 hidnplayr 117
        DEBUGF  1,"TCP_pull_out_of_band\n"
1733 hidnplayr 118
 
2390 hidnplayr 119
        ;;;; 1282-1305
1733 hidnplayr 120
 
2390 hidnplayr 121
        ret
1733 hidnplayr 122
 
123
 
124
 
125
 
126
 
127
 
128
 
129
 
130
;-------------------------
131
;
132
; TCP_drop
133
;
134
;  IN:  eax = socket ptr
135
;       ebx = error number
136
;
137
;  OUT: eax = socket ptr
138
;
139
;-------------------------
140
align 4
141
TCP_drop:
142
 
2390 hidnplayr 143
        DEBUGF  1,"TCP_drop\n"
1733 hidnplayr 144
 
2390 hidnplayr 145
        cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
146
        jb      .no_syn_received
1733 hidnplayr 147
 
2390 hidnplayr 148
        mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
1733 hidnplayr 149
 
2390 hidnplayr 150
        call    TCP_output
1733 hidnplayr 151
 
152
;;; TODO: update stats
153
 
2390 hidnplayr 154
        jmp     TCP_close
1733 hidnplayr 155
 
156
  .no_syn_received:
157
 
158
;;; TODO: update stats
159
 
160
;;; TODO: check if error code is "Connection timed out' and handle accordingly
161
 
2390 hidnplayr 162
        mov     [eax + SOCKET.errorcode], ebx
1733 hidnplayr 163
 
164
 
165
 
166
 
167
 
168
 
169
 
170
 
171
;-------------------------
172
;
173
; TCP_close
174
;
175
;  IN:  eax = socket ptr
176
;  OUT: eax = socket ptr
177
;
178
;-------------------------
179
align 4
180
TCP_close:
181
 
2390 hidnplayr 182
        DEBUGF  1,"TCP_close\n"
1733 hidnplayr 183
 
184
;;; TODO: update RTT and mean deviation
185
;;; TODO: update slow start threshold
186
;;; TODO: release connection resources
187
 
2390 hidnplayr 188
        call    SOCKET_is_disconnected
1733 hidnplayr 189
 
2390 hidnplayr 190
        ret
1733 hidnplayr 191
 
192
 
193
 
194
 
195
 
196
 
197
 
198
 
199
 
200
 
201
;-------------------------
202
;
203
; TCP_outflags
204
;
205
;  IN:  eax = socket ptr
206
;
207
;  OUT: edx = flags
208
;
209
;-------------------------
210
align 4
211
TCP_outflags:
212
 
2390 hidnplayr 213
        mov     edx, [eax + TCP_SOCKET.t_state]
214
        movzx   edx, byte [edx + .flaglist]
1733 hidnplayr 215
 
2390 hidnplayr 216
        DEBUGF  1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
1733 hidnplayr 217
 
2390 hidnplayr 218
        ret
1733 hidnplayr 219
 
220
  .flaglist:
221
 
2390 hidnplayr 222
        db      TH_RST + TH_ACK         ; TCPS_CLOSED
223
        db      0                       ; TCPS_LISTEN
224
        db      TH_SYN                  ; TCPS_SYN_SENT
225
        db      TH_SYN + TH_ACK         ; TCPS_SYN_RECEIVED
226
        db               TH_ACK         ; TCPS_ESTABLISHED
227
        db               TH_ACK         ; TCPS_CLOSE_WAIT
228
        db      TH_SYN + TH_ACK         ; TCPS_FIN_WAIT_1
229
        db      TH_SYN + TH_ACK         ; TCPS_CLOSING
230
        db      TH_SYN + TH_ACK         ; TCPS_LAST_ACK
231
        db               TH_ACK         ; TCPS_FIN_WAIT_2
232
        db               TH_ACK         ; TCPS_TIMED_WAIT
1733 hidnplayr 233
 
234
 
235
 
236
 
237
 
238
 
239
;---------------------------------------
240
;
1830 hidnplayr 241
; The fast way to send an ACK/RST/keepalive segment
1733 hidnplayr 242
;
243
; TCP_respond_socket:
244
;
245
;  IN:  ebx = socket ptr
246
;        cl = flags
247
;
248
;--------------------------------------
249
align 4
250
TCP_respond_socket:
251
 
2390 hidnplayr 252
        DEBUGF  1,"TCP_respond_socket\n"
1733 hidnplayr 253
 
254
;---------------------
255
; Create the IP packet
256
 
2390 hidnplayr 257
        push    cx ebx
258
        mov     eax, [ebx + IP_SOCKET.RemoteIP]
259
        mov     ebx, [ebx + IP_SOCKET.LocalIP]
260
        mov     ecx, sizeof.TCP_header
261
        mov     di , IP_PROTO_TCP shl 8 + 128
262
        call    IPv4_output
263
        test    edi, edi
264
        jz      .error
265
        pop     esi cx
266
        push    edx eax
1733 hidnplayr 267
 
268
;-----------------------------------------------
269
; Fill in the TCP header by using the socket ptr
270
 
2390 hidnplayr 271
        mov     ax, [esi + TCP_SOCKET.LocalPort]
272
        rol     ax, 8
273
        stosw
274
        mov     ax, [esi + TCP_SOCKET.RemotePort]
275
        rol     ax, 8
276
        stosw
277
        mov     eax, [esi + TCP_SOCKET.SND_NXT]
278
        bswap   eax
279
        stosd
280
        mov     eax, [esi + TCP_SOCKET.RCV_NXT]
281
        bswap   eax
282
        stosd
283
        mov     al, 0x50        ; Dataoffset: 20 bytes (TCP_header.DataOffset)
284
        stosb
285
        mov     al, cl
286
        stosb
1830 hidnplayr 287
;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
288
;        rol     ax, 8
2390 hidnplayr 289
        mov     ax, 0x00a0      ;;;;;;; FIXME
290
        stosw                   ; window
291
        xor     eax, eax
292
        stosd                   ; checksum + urgentpointer
1733 hidnplayr 293
 
294
;---------------------
295
; Fill in the checksum
296
 
297
  .checksum:
2390 hidnplayr 298
        sub     edi, sizeof.TCP_header
299
        mov     ecx, sizeof.TCP_header
300
        xchg    esi, edi
301
        TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
302
        mov     [esi+TCP_header.Checksum], dx
1733 hidnplayr 303
 
304
;--------------------
305
; And send the segment
306
 
2390 hidnplayr 307
        call    [ebx + NET_DEVICE.transmit]
308
        ret
1733 hidnplayr 309
 
310
  .error:
2390 hidnplayr 311
        DEBUGF  1,"TCP_respond failed\n"
312
        add     esp, 2+4
1733 hidnplayr 313
 
2390 hidnplayr 314
        ret
1733 hidnplayr 315
 
316
 
317
 
318
 
319
 
320
 
321
 
322
 
323
;-------------------------
324
; TCP_respond.segment:
325
;
2600 hidnplayr 326
;  IN:  edx = segment ptr (a previously received segment)
2308 hidnplayr 327
;       edi = ptr to dest and src IPv4 addresses
1733 hidnplayr 328
;        cl = flags
329
 
330
align 4
331
TCP_respond_segment:
332
 
2390 hidnplayr 333
        DEBUGF  1,"TCP_respond_segment\n"
1733 hidnplayr 334
 
335
;---------------------
336
; Create the IP packet
337
 
2600 hidnplayr 338
        push    cx edx
2390 hidnplayr 339
        mov     ebx, [edi + 4]
340
        mov     eax, [edi]
341
        mov     ecx, sizeof.TCP_header
342
        mov     di , IP_PROTO_TCP shl 8 + 128
343
        call    IPv4_output
344
        jz      .error
2600 hidnplayr 345
        pop     esi cx
1733 hidnplayr 346
 
2390 hidnplayr 347
        push    edx eax
1733 hidnplayr 348
 
349
;---------------------------------------------------
350
; Fill in the TCP header by using a received segment
351
 
2390 hidnplayr 352
        mov     ax, [esi + TCP_header.DestinationPort]
353
        rol     ax, 8
354
        stosw
355
        mov     ax, [esi + TCP_header.SourcePort]
356
        rol     ax, 8
357
        stosw
358
        mov     eax, [esi + TCP_header.AckNumber]
359
        bswap   eax
360
        stosd
361
        xor     eax, eax
362
        stosd
363
        mov     al, 0x50        ; Dataoffset: 20 bytes (sizeof.TCP_header)
364
        stosb
365
        mov     al, cl
366
        stosb
367
        mov     ax, 1280
368
        rol     ax, 8
369
        stosw                   ; window
370
        xor     eax, eax
371
        stosd                   ; checksum + urgentpointer
1733 hidnplayr 372
 
373
;---------------------
374
; Fill in the checksum
375
 
376
  .checksum:
2390 hidnplayr 377
        lea     esi, [edi - sizeof.TCP_header]
378
        mov     ecx, sizeof.TCP_header
379
        TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\      ; FIXME
380
                     (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
381
        mov     [esi+TCP_header.Checksum], dx
1733 hidnplayr 382
 
383
;--------------------
384
; And send the segment
385
 
2390 hidnplayr 386
        call    [ebx + NET_DEVICE.transmit]
387
        ret
1733 hidnplayr 388
 
389
  .error:
2390 hidnplayr 390
        DEBUGF  1,"TCP_respond failed\n"
391
        add     esp, 2+4
1733 hidnplayr 392
 
2390 hidnplayr 393
        ret
2362 hidnplayr 394
 
395
 
396
 
397
macro TCP_set_persist socket {
398
 
399
;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
400
;int tt;
401
;
402
;tp->t_flags &= ~TF_PREVVALID;
403
;
404
;if (tcp_timer_active(tp, TT_REXMT))
405
;        panic("tcp_setpersist: retransmit pending");
406
;
407
;; Start/restart persistance timer.
408
;
409
;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX);
410
;tcp_timer_activate(tp, TT_PERSIST, tt);
411
;
412
;if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
413
;        tp->t_rxtshift++;
414
 
2612 hidnplayr 415
}