Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3555 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4423 Serge 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
3555 Serge 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
 
3589 Serge 30
        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_usrclosed: %x\n", eax
3555 Serge 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
        pop     ebx
61
        ret
62
 
63
  .last_ack:
64
        mov     [eax + TCP_SOCKET.t_state], TCPS_LAST_ACK
65
        pop     ebx
66
        ret
67
 
68
  .disc:
69
        call    SOCKET_is_disconnected
70
  .ret:
71
        pop     ebx
72
        ret
73
 
74
 
4265 Serge 75
;-------------------------
76
;
77
; TCP_connect
78
;
79
;  IN:  eax = socket ptr
80
;  OUT: eax = 0 ok / -1 error
81
;       ebx = error code
82
;
83
;-------------------------
84
align 4
85
TCP_connect:
3555 Serge 86
 
4265 Serge 87
        test    [eax + SOCKET.state], SS_ISCONNECTED
88
        jnz     .eisconn
3555 Serge 89
 
4265 Serge 90
        push    eax edx
91
        lea     ecx, [eax + SOCKET.mutex]
92
        call    mutex_lock
93
        pop     edx eax
94
 
95
; Fill in local IP
96
        cmp     [eax + IP_SOCKET.LocalIP], 0
97
        jne     @f
98
        push    [IP_LIST + 4]                                   ; FIXME: use correct local IP
99
        pop     [eax + IP_SOCKET.LocalIP]
100
 
101
; Fill in remote port and IP
102
        pushw   [edx + 2]
103
        pop     [eax + TCP_SOCKET.RemotePort]
104
 
105
        pushd   [edx + 4]
106
        pop     [eax + IP_SOCKET.RemoteIP]
107
 
108
; Find a local port, if user didnt define one
109
        cmp     [eax + TCP_SOCKET.LocalPort], 0
110
        jne     @f
111
        call    SOCKET_find_port
112
       @@:
113
 
114
; Start the TCP sequence
115
        mov     [eax + TCP_SOCKET.timer_persist], 0
116
        mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
117
 
118
        push    [TCP_sequence_num]
119
        add     [TCP_sequence_num], 6400
120
        pop     [eax + TCP_SOCKET.ISS]
121
        mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
122
 
123
        TCP_sendseqinit eax
124
 
125
        mov     ebx, eax
126
        lea     eax, [ebx + STREAM_SOCKET.snd]
127
        call    SOCKET_ring_create
128
        test    eax, eax
129
        jz      .nomem
130
 
131
        lea     eax, [ebx + STREAM_SOCKET.rcv]
132
        call    SOCKET_ring_create
133
        test    eax, eax
134
        jz      .nomem
135
 
136
        push    ebx
137
        lea     ecx, [ebx + SOCKET.mutex]
138
        call    mutex_unlock
139
        pop     eax
140
 
141
        call    SOCKET_is_connecting
142
 
143
; Now send the SYN packet to remote end
144
        push    eax
145
        call    TCP_output
146
        pop     eax
147
 
148
  .block:
149
        test    [eax + SOCKET.options], SO_NONBLOCK
150
        jz      .waitforit
151
 
152
        xor     eax, eax
153
        dec     eax
154
        mov     ebx, EINPROGRESS
155
        ret
156
 
157
  .nomem:
158
        xor     eax, eax
159
        dec     eax
160
        mov     ebx, ENOMEM
161
        ret
162
 
163
  .eisconn:
164
        xor     eax, eax
165
        dec     eax
166
        mov     ebx, EISCONN
167
        ret
168
 
169
  .waitforit:
170
        push    eax
171
        stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
172
        pop     ebx
173
        mov     [ebx + TCP_SOCKET.timer_connect], eax
174
        mov     eax, ebx
175
 
176
  .loop:
177
        cmp     [eax + SOCKET.errorcode], 0
178
        jne     .fail
179
        cmp     [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
180
        je      .established
181
 
182
        call    SOCKET_block
183
        jmp     .loop
184
 
185
  .timeout:
186
        mov     eax, [esp+4]
187
        mov     [eax + SOCKET.errorcode], ETIMEDOUT
188
        and     [eax + SOCKET.state], not SS_ISCONNECTING
189
        call    SOCKET_notify.unblock
190
        ret     4
191
 
192
  .fail:
193
        mov     ebx, [eax + SOCKET.errorcode]
194
        mov     [eax + SOCKET.errorcode], 0                     ; Clear the error, we only need to send it to the caller once
195
        xor     eax, eax
196
        dec     eax
197
        ret
198
 
199
  .established:
200
        stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
201
 
202
        xor     eax, eax
3555 Serge 203
        ret