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 |