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