Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
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
 
18
;-------------------------
19
;
20
; TCP_usrclose
21
;
22
; Move connection to next state, based on process close.
23
;
24
;  IN:  eax = socket ptr
25
;
26
;-------------------------
27
align 4
28
TCP_usrclosed:
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
 
39
        dd      .close                  ; TCPS_CLOSED
40
        dd      .close                  ; TCPS_LISTEN
41
        dd      .close                  ; TCPS_SYN_SENT
42
        dd      .wait1                  ; TCPS_SYN_RECEIVED
43
        dd      .wait1                  ; TCPS_ESTABLISHED
44
        dd      .last_ack               ; TCPS_CLOSE_WAIT
45
        dd      .ret                    ; TCPS_FIN_WAIT_1
46
        dd      .ret                    ; TCPS_CLOSING
47
        dd      .ret                    ; TCPS_LAST_ACK
48
        dd      .disc                   ; TCPS_FIN_WAIT_2
49
        dd      .disc                   ; TCPS_TIMED_WAIT
50
 
51
 
52
  .close:
53
        mov     [eax + TCP_SOCKET.t_state], TCPS_CLOSED
54
        call    TCP_close
55
        pop     ebx
56
        ret
57
 
58
  .wait1:
59
        mov     [eax + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1
60
        ; TODO: set timer?
61
        pop     ebx
62
        ret
63
 
64
  .last_ack:
65
        mov     [eax + TCP_SOCKET.t_state], TCPS_LAST_ACK
66
        pop     ebx
67
        ret
68
 
69
  .disc:
70
        call    SOCKET_is_disconnected
71
        ; TODO: set timer?
72
  .ret:
73
        pop     ebx
74
        ret
75
 
76
 
4030 hidnplayr 77
;-------------------------
78
;
79
; TCP_connect
80
;
81
;  IN:  eax = socket ptr
82
;  OUT: eax = 0 ok / -1 error
83
;       ebx = error code
84
;
85
;-------------------------
86
align 4
87
TCP_connect:
3545 hidnplayr 88
 
4030 hidnplayr 89
        test    [eax + SOCKET.state], SS_ISCONNECTED
90
        jnz     .eisconn
3545 hidnplayr 91
 
4035 hidnplayr 92
        push    eax edx
4030 hidnplayr 93
        lea     ecx, [eax + SOCKET.mutex]
94
        call    mutex_lock
4035 hidnplayr 95
        pop     edx eax
4030 hidnplayr 96
 
97
; Fill in local IP
98
        cmp     [eax + IP_SOCKET.LocalIP], 0
99
        jne     @f
100
        push    [IP_LIST + 4]                                   ; FIXME: use correct local IP
101
        pop     [eax + IP_SOCKET.LocalIP]
102
 
103
; Fill in remote port and IP
104
        pushw   [edx + 2]
105
        pop     [eax + TCP_SOCKET.RemotePort]
106
 
107
        pushd   [edx + 4]
108
        pop     [eax + IP_SOCKET.RemoteIP]
109
 
110
; Find a local port, if user didnt define one
111
        cmp     [eax + TCP_SOCKET.LocalPort], 0
112
        jne     @f
113
        call    SOCKET_find_port
114
       @@:
115
 
116
; Start the TCP sequence
117
        mov     [eax + TCP_SOCKET.timer_persist], 0
118
        mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
119
 
120
        push    [TCP_sequence_num]
121
        add     [TCP_sequence_num], 6400
122
        pop     [eax + TCP_SOCKET.ISS]
123
        mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
124
 
125
        TCP_sendseqinit eax
126
 
127
        mov     ebx, eax
128
        lea     eax, [ebx + STREAM_SOCKET.snd]
129
        call    SOCKET_ring_create
130
        test    eax, eax
131
        jz      .nomem
132
 
133
        lea     eax, [ebx + STREAM_SOCKET.rcv]
134
        call    SOCKET_ring_create
135
        test    eax, eax
136
        jz      .nomem
137
 
138
        push    ebx
139
        lea     ecx, [ebx + SOCKET.mutex]
140
        call    mutex_unlock
141
        pop     eax
142
 
143
        call    SOCKET_is_connecting
144
 
145
; Now send the SYN packet to remote end
146
        push    eax
147
        call    TCP_output
148
        pop     eax
149
 
150
  .block:
151
        test    [eax + SOCKET.options], SO_NONBLOCK
152
        jz      .waitforit
153
 
154
        xor     eax, eax
155
        dec     eax
156
        mov     ebx, EINPROGRESS
157
        ret
158
 
159
  .nomem:
160
        xor     eax, eax
161
        dec     eax
162
        mov     ebx, ENOMEM
163
        ret
164
 
165
  .eisconn:
166
        xor     eax, eax
167
        dec     eax
168
        mov     ebx, EISCONN
169
        ret
170
 
171
  .waitforit:
172
        push    eax
173
        stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
174
        pop     ebx
175
        mov     [ebx + TCP_SOCKET.timer_connect], eax
176
        mov     eax, ebx
177
 
178
  .loop:
179
        cmp     [eax + SOCKET.errorcode], 0
180
        jne     .fail
181
        cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
182
        je      .established
183
 
184
        call    SOCKET_block
185
        jmp     .loop
186
 
187
  .timeout:
188
        mov     eax, [esp+4]
189
        mov     [eax + SOCKET.errorcode], ETIMEDOUT
190
        and     [eax + SOCKET.state], not SS_ISCONNECTING
191
        call    SOCKET_notify.unblock
192
        ret     4
193
 
194
  .fail:
195
        mov     ebx, [eax + SOCKET.errorcode]
196
        mov     [eax + SOCKET.errorcode], 0                     ; Clear the error, we only need to send it to the caller once
197
        xor     eax, eax
198
        dec     eax
199
        ret
200
 
201
  .established:
202
        stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
203
 
204
        xor     eax, eax
205
        ret
206
 
207
 
208
 
209
 
3545 hidnplayr 210
;-------------------------
211
;
212
; TCP_disconnect
213
;
214
;  IN:  eax = socket ptr
215
;  OUT: eax = socket ptr
216
;
217
;-------------------------
218
align 4
219
TCP_disconnect:
220
 
3556 hidnplayr 221
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_disconnect: %x\n", eax
3545 hidnplayr 222
 
223
        cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
224
        jb      TCP_close
225
 
226
 
227
; TODO: implement LINGER ?
228
 
229
        call    SOCKET_is_disconnecting
230
        call    TCP_usrclosed
3652 hidnplayr 231
 
232
        push    eax
3545 hidnplayr 233
        call    TCP_output
3652 hidnplayr 234
        pop     eax
3545 hidnplayr 235
 
236
        ret