Rev 3652 | Rev 4035 | 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 | |
4030 | hidnplayr | 92 | push eax |
93 | lea ecx, [eax + SOCKET.mutex] |
||
94 | call mutex_lock |
||
95 | pop eax |
||
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 |