Subversion Repositories Kolibri OS

Rev

Rev 7679 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
10051 ace_dent 3
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved.    ;;
3545 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
 
5976 hidnplayr 18
;-----------------------------------------------------------------;
19
;                                                                 ;
6011 hidnplayr 20
; tcp_usrclosed                                                   ;
5976 hidnplayr 21
;                                                                 ;
22
;  IN:  eax = socket ptr                                          ;
23
;                                                                 ;
24
;  OUT: /                                                         ;
25
;                                                                 ;
26
;-----------------------------------------------------------------;
3545 hidnplayr 27
align 4
6011 hidnplayr 28
tcp_usrclosed:
3545 hidnplayr 29
 
3556 hidnplayr 30
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_usrclosed: %x\n", eax
3545 hidnplayr 31
 
32
        push    ebx
33
        mov     ebx, [eax + TCP_SOCKET.t_state]
34
        mov     ebx, dword [.switch + ebx*4]
35
        jmp     ebx
36
 
37
  .switch:
38
        dd      .close                  ; TCPS_CLOSED
39
        dd      .close                  ; TCPS_LISTEN
40
        dd      .close                  ; TCPS_SYN_SENT
41
        dd      .wait1                  ; TCPS_SYN_RECEIVED
42
        dd      .wait1                  ; TCPS_ESTABLISHED
43
        dd      .last_ack               ; TCPS_CLOSE_WAIT
44
        dd      .ret                    ; TCPS_FIN_WAIT_1
45
        dd      .ret                    ; TCPS_CLOSING
46
        dd      .ret                    ; TCPS_LAST_ACK
47
        dd      .disc                   ; TCPS_FIN_WAIT_2
48
        dd      .disc                   ; TCPS_TIMED_WAIT
49
 
50
  .close:
51
        mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
6011 hidnplayr 52
        call    tcp_close
3545 hidnplayr 53
        pop     ebx
54
        ret
55
 
56
  .wait1:
57
        mov     [eax + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
58
        pop     ebx
59
        ret
60
 
61
  .last_ack:
62
        mov     [eax + TCP_SOCKET.t_state], TCPS_LAST_ACK
63
        pop     ebx
64
        ret
65
 
66
  .disc:
6011 hidnplayr 67
        call    socket_is_disconnected
3545 hidnplayr 68
  .ret:
69
        pop     ebx
70
        ret
71
 
72
 
5976 hidnplayr 73
;-----------------------------------------------------------------;
74
;                                                                 ;
6011 hidnplayr 75
; tcp_connect                                                     ;
5976 hidnplayr 76
;                                                                 ;
77
;  IN:  eax = socket ptr                                          ;
78
;                                                                 ;
79
;  OUT: eax = 0 on success                                        ;
80
;       eax = -1 on error                                         ;
81
;       ebx = error code on error                                 ;
82
;                                                                 ;
83
;-----------------------------------------------------------------;
4030 hidnplayr 84
align 4
6011 hidnplayr 85
tcp_connect:
3545 hidnplayr 86
 
4030 hidnplayr 87
        test    [eax + SOCKET.state], SS_ISCONNECTED
88
        jnz     .eisconn
3545 hidnplayr 89
 
4035 hidnplayr 90
        push    eax edx
4030 hidnplayr 91
        lea     ecx, [eax + SOCKET.mutex]
92
        call    mutex_lock
6912 hidnplayr 93
 
94
        mov     ebx, eax
95
        lea     eax, [ebx + STREAM_SOCKET.snd]
96
        call    socket_ring_create
97
        test    eax, eax
98
        jz      .nomem
99
 
100
        lea     eax, [ebx + STREAM_SOCKET.rcv]
101
        call    socket_ring_create
102
        test    eax, eax
103
        jz      .nomem
4035 hidnplayr 104
        pop     edx eax
4030 hidnplayr 105
 
106
; Fill in remote port and IP
107
        pushw   [edx + 2]
108
        pop     [eax + TCP_SOCKET.RemotePort]
109
 
110
        pushd   [edx + 4]
6912 hidnplayr 111
        pop     [eax + TCP_SOCKET.RemoteIP]
4030 hidnplayr 112
 
6912 hidnplayr 113
; Find route to host
114
        pusha
115
        push    eax
116
        mov     ebx, [eax + TCP_SOCKET.device]
117
        mov     edx, [eax + TCP_SOCKET.LocalIP]
118
        mov     eax, [eax + TCP_SOCKET.RemoteIP]
119
        call    ipv4_route
120
        test    eax, eax
121
        jz      .enoroute
122
        pop     eax
7679 hidnplayr 123
        mov     ebx, [net_device_list + edi]
6912 hidnplayr 124
        mov     [eax + TCP_SOCKET.device], ebx
125
        mov     [eax + TCP_SOCKET.LocalIP], edx
126
        popa
127
 
4030 hidnplayr 128
; Find a local port, if user didnt define one
129
        cmp     [eax + TCP_SOCKET.LocalPort], 0
130
        jne     @f
6011 hidnplayr 131
        call    socket_find_port
4030 hidnplayr 132
       @@:
133
 
6912 hidnplayr 134
; Compute window scaling factor
135
        push    ecx
136
        xor     ecx, ecx
137
        mov     ebx, TCP_max_win
138
  @@:
139
        cmp     ebx, SOCKET_BUFFER_SIZE
140
        ja      @f
141
        shl     ebx, 1
142
        inc     ecx
143
        cmp     ecx, TCP_max_winshift
144
        jb      @r
145
  @@:
146
        mov     [eax + TCP_SOCKET.request_r_scale], cl
147
        pop     ecx
148
 
149
        call    socket_is_connecting
150
        inc     [TCPS_connattempt]
151
 
4030 hidnplayr 152
        mov     [eax + TCP_SOCKET.timer_persist], 0
153
        mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
154
 
6912 hidnplayr 155
        mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
156
 
4030 hidnplayr 157
        push    [TCP_sequence_num]
6912 hidnplayr 158
        add     [TCP_sequence_num], TCP_ISSINCR/2
4030 hidnplayr 159
        pop     [eax + TCP_SOCKET.ISS]
160
 
6011 hidnplayr 161
        tcp_sendseqinit eax
4030 hidnplayr 162
 
6912 hidnplayr 163
        push    eax
164
        lea     ecx, [eax + SOCKET.mutex]
4030 hidnplayr 165
        call    mutex_unlock
166
        pop     eax
167
 
168
; Now send the SYN packet to remote end
169
        push    eax
6011 hidnplayr 170
        call    tcp_output
4030 hidnplayr 171
        pop     eax
172
 
173
        test    [eax + SOCKET.options], SO_NONBLOCK
174
        jz      .waitforit
175
 
176
        xor     eax, eax
177
        dec     eax
178
        mov     ebx, EINPROGRESS
179
        ret
180
 
181
  .nomem:
6912 hidnplayr 182
        pop     edx eax
4030 hidnplayr 183
        xor     eax, eax
184
        dec     eax
185
        mov     ebx, ENOMEM
186
        ret
187
 
188
  .eisconn:
189
        xor     eax, eax
190
        dec     eax
191
        mov     ebx, EISCONN
192
        ret
193
 
6912 hidnplayr 194
  .enoroute:
195
        pop     eax
196
        popa
197
        xor     eax, eax
198
        dec     eax
199
        mov     ebx, EADDRNOTAVAIL
200
        ret
201
 
4030 hidnplayr 202
  .waitforit:
203
        push    eax
204
        stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
205
        pop     ebx
206
        mov     [ebx + TCP_SOCKET.timer_connect], eax
207
        mov     eax, ebx
208
 
209
  .loop:
210
        cmp     [eax + SOCKET.errorcode], 0
211
        jne     .fail
212
        cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
213
        je      .established
214
 
6011 hidnplayr 215
        call    socket_block
4030 hidnplayr 216
        jmp     .loop
217
 
218
  .timeout:
219
        mov     eax, [esp+4]
220
        mov     [eax + SOCKET.errorcode], ETIMEDOUT
221
        and     [eax + SOCKET.state], not SS_ISCONNECTING
6011 hidnplayr 222
        call    socket_notify
4030 hidnplayr 223
        ret     4
224
 
225
  .fail:
226
        mov     ebx, [eax + SOCKET.errorcode]
227
        mov     [eax + SOCKET.errorcode], 0                     ; Clear the error, we only need to send it to the caller once
228
        xor     eax, eax
229
        dec     eax
230
        ret
231
 
232
  .established:
233
        stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
234
        xor     eax, eax
10051 ace_dent 235
        ret