Rev 4423 | Rev 5565 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4423 | Rev 5201 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2014. 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 | ;; and Clevermouse. ;; |
9 | ;; and Clevermouse. ;; |
10 | ;; ;; |
10 | ;; ;; |
11 | ;; Based on code by mike.dld ;; |
11 | ;; Based on code by mike.dld ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; Version 2, June 1991 ;; |
14 | ;; Version 2, June 1991 ;; |
15 | ;; ;; |
15 | ;; ;; |
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | 17 | ||
18 | $Revision: 4423 $ |
18 | $Revision: 5201 $ |
19 | 19 | ||
20 | struct SOCKET |
20 | struct SOCKET |
21 | 21 | ||
22 | NextPtr dd ? ; pointer to next socket in list |
22 | NextPtr dd ? ; pointer to next socket in list |
23 | PrevPtr dd ? ; pointer to previous socket in list |
23 | PrevPtr dd ? ; pointer to previous socket in list |
24 | Number dd ? ; socket number |
24 | Number dd ? ; socket number |
25 | 25 | ||
26 | mutex MUTEX |
26 | mutex MUTEX |
27 | 27 | ||
28 | PID dd ? ; process ID |
28 | PID dd ? ; process ID |
29 | TID dd ? ; thread ID |
29 | TID dd ? ; thread ID |
30 | Domain dd ? ; INET/LOCAL/.. |
30 | Domain dd ? ; INET/LOCAL/.. |
31 | Type dd ? ; RAW/STREAM/DGRAM |
31 | Type dd ? ; RAW/STREAM/DGRAM |
32 | Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP |
32 | Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP |
33 | errorcode dd ? |
33 | errorcode dd ? |
34 | device dd ? ; driver pointer, socket pointer if it's an LOCAL socket |
34 | device dd ? ; driver pointer, socket pointer if it's an LOCAL socket |
35 | 35 | ||
36 | options dd ? |
36 | options dd ? |
37 | state dd ? |
37 | state dd ? |
38 | backlog dw ? ; how many incoming connections that can be queued |
38 | backlog dw ? ; how many incoming connections that can be queued |
39 | 39 | ||
40 | snd_proc dd ? |
40 | snd_proc dd ? |
41 | rcv_proc dd ? |
41 | rcv_proc dd ? |
42 | connect_proc dd ? |
42 | connect_proc dd ? |
43 | 43 | ||
44 | ends |
44 | ends |
45 | 45 | ||
46 | struct IP_SOCKET SOCKET |
46 | struct IP_SOCKET SOCKET |
47 | 47 | ||
48 | LocalIP rd 4 ; network byte order |
48 | LocalIP rd 4 ; network byte order |
49 | RemoteIP rd 4 ; network byte order |
49 | RemoteIP rd 4 ; network byte order |
50 | 50 | ||
51 | ends |
51 | ends |
52 | 52 | ||
53 | struct TCP_SOCKET IP_SOCKET |
53 | struct TCP_SOCKET IP_SOCKET |
54 | 54 | ||
55 | LocalPort dw ? ; network byte order |
55 | LocalPort dw ? ; network byte order |
56 | RemotePort dw ? ; network byte order |
56 | RemotePort dw ? ; network byte order |
57 | 57 | ||
58 | t_state dd ? ; TCB state |
58 | t_state dd ? ; TCB state |
59 | t_rxtshift db ? |
59 | t_rxtshift db ? |
60 | rb 3 ; align |
60 | rb 3 ; align |
61 | t_rxtcur dd ? |
61 | t_rxtcur dd ? |
62 | t_dupacks dd ? |
62 | t_dupacks dd ? |
63 | t_maxseg dd ? |
63 | t_maxseg dd ? |
64 | t_force dd ? |
64 | t_force dd ? |
65 | t_flags dd ? |
65 | t_flags dd ? |
66 | 66 | ||
67 | ;--------------- |
67 | ;--------------- |
68 | ; RFC783 page 21 |
68 | ; RFC783 page 21 |
69 | 69 | ||
70 | ; send sequence |
70 | ; send sequence |
71 | SND_UNA dd ? ; sequence number of unack'ed sent Packets |
71 | SND_UNA dd ? ; sequence number of unack'ed sent Packets |
72 | SND_NXT dd ? ; next send sequence number to use |
72 | SND_NXT dd ? ; next send sequence number to use |
73 | SND_UP dd ? ; urgent pointer |
73 | SND_UP dd ? ; urgent pointer |
74 | SND_WL1 dd ? ; window minus one |
74 | SND_WL1 dd ? ; window minus one |
75 | SND_WL2 dd ? ; |
75 | SND_WL2 dd ? ; |
76 | ISS dd ? ; initial send sequence number |
76 | ISS dd ? ; initial send sequence number |
77 | SND_WND dd ? ; send window |
77 | SND_WND dd ? ; send window |
78 | 78 | ||
79 | ; receive sequence |
79 | ; receive sequence |
80 | RCV_WND dd ? ; receive window |
80 | RCV_WND dd ? ; receive window |
81 | RCV_NXT dd ? ; next receive sequence number to use |
81 | RCV_NXT dd ? ; next receive sequence number to use |
82 | RCV_UP dd ? ; urgent pointer |
82 | RCV_UP dd ? ; urgent pointer |
83 | IRS dd ? ; initial receive sequence number |
83 | IRS dd ? ; initial receive sequence number |
84 | 84 | ||
85 | ;--------------------- |
85 | ;--------------------- |
86 | ; Additional variables |
86 | ; Additional variables |
87 | 87 | ||
88 | ; receive variables |
88 | ; receive variables |
89 | RCV_ADV dd ? |
89 | RCV_ADV dd ? |
90 | 90 | ||
91 | ; retransmit variables |
91 | ; retransmit variables |
92 | SND_MAX dd ? |
92 | SND_MAX dd ? |
93 | 93 | ||
94 | ; congestion control |
94 | ; congestion control |
95 | SND_CWND dd ? ; congestion window |
95 | SND_CWND dd ? ; congestion window |
96 | SND_SSTHRESH dd ? ; slow start threshold |
96 | SND_SSTHRESH dd ? ; slow start threshold |
97 | 97 | ||
98 | ;---------------------- |
98 | ;---------------------- |
99 | ; Transmit timing stuff |
99 | ; Transmit timing stuff |
100 | t_idle dd ? |
100 | t_idle dd ? |
101 | t_rtt dd ? |
101 | t_rtt dd ? |
102 | t_rtseq dd ? |
102 | t_rtseq dd ? |
103 | t_srtt dd ? |
103 | t_srtt dd ? |
104 | t_rttvar dd ? |
104 | t_rttvar dd ? |
105 | t_rttmin dd ? |
105 | t_rttmin dd ? |
106 | max_sndwnd dd ? |
106 | max_sndwnd dd ? |
107 | 107 | ||
108 | ;----------------- |
108 | ;----------------- |
109 | ; Out-of-band data |
109 | ; Out-of-band data |
110 | t_oobflags dd ? |
110 | t_oobflags dd ? |
111 | t_iobc dd ? |
111 | t_iobc dd ? |
112 | t_softerror dd ? |
112 | t_softerror dd ? |
113 | 113 | ||
114 | 114 | ||
115 | ;--------- |
115 | ;--------- |
116 | ; RFC 1323 ; the order of next 4 elements may not change |
116 | ; RFC 1323 ; the order of next 4 elements may not change |
117 | 117 | ||
118 | SND_SCALE db ? |
118 | SND_SCALE db ? |
119 | RCV_SCALE db ? |
119 | RCV_SCALE db ? |
120 | requested_s_scale db ? |
120 | requested_s_scale db ? |
121 | request_r_scale db ? |
121 | request_r_scale db ? |
122 | 122 | ||
123 | ts_recent dd ? ; a copy of the most-recent valid timestamp from the other end |
123 | ts_recent dd ? ; a copy of the most-recent valid timestamp from the other end |
124 | ts_recent_age dd ? |
124 | ts_recent_age dd ? |
125 | last_ack_sent dd ? |
125 | last_ack_sent dd ? |
126 | 126 | ||
127 | 127 | ||
128 | ;------- |
128 | ;------- |
129 | ; Timers |
129 | ; Timers |
130 | timer_flags dd ? |
130 | timer_flags dd ? |
131 | timer_retransmission dd ? ; rexmt |
131 | timer_retransmission dd ? ; rexmt |
132 | timer_persist dd ? |
132 | timer_persist dd ? |
133 | timer_keepalive dd ? ; keepalive/syn timeout |
133 | timer_keepalive dd ? ; keepalive/syn timeout |
134 | timer_timed_wait dd ? ; also used as 2msl timer |
134 | timer_timed_wait dd ? ; also used as 2msl timer |
135 | timer_connect dd ? |
135 | timer_connect dd ? |
136 | 136 | ||
137 | ; extra |
137 | ; extra |
138 | 138 | ||
139 | ts_ecr dd ? ; timestamp echo reply |
139 | ts_ecr dd ? ; timestamp echo reply |
140 | ts_val dd ? |
140 | ts_val dd ? |
141 | 141 | ||
142 | seg_next dd ? ; re-assembly queue |
142 | seg_next dd ? ; re-assembly queue |
143 | 143 | ||
144 | ends |
144 | ends |
145 | 145 | ||
146 | struct UDP_SOCKET IP_SOCKET |
146 | struct UDP_SOCKET IP_SOCKET |
147 | 147 | ||
148 | LocalPort dw ? ; network byte order |
148 | LocalPort dw ? ; network byte order |
149 | RemotePort dw ? ; network byte order |
149 | RemotePort dw ? ; network byte order |
150 | 150 | ||
151 | ends |
151 | ends |
152 | 152 | ||
153 | 153 | ||
154 | struct ICMP_SOCKET IP_SOCKET |
154 | struct ICMP_SOCKET IP_SOCKET |
155 | 155 | ||
156 | Identifier dw ? |
156 | Identifier dw ? |
157 | 157 | ||
158 | ends |
158 | ends |
159 | 159 | ||
160 | 160 | ||
161 | struct RING_BUFFER |
161 | struct RING_BUFFER |
162 | 162 | ||
163 | mutex MUTEX |
163 | mutex MUTEX |
164 | start_ptr dd ? ; Pointer to start of buffer |
164 | start_ptr dd ? ; Pointer to start of buffer |
165 | end_ptr dd ? ; pointer to end of buffer |
165 | end_ptr dd ? ; pointer to end of buffer |
166 | read_ptr dd ? ; Read pointer |
166 | read_ptr dd ? ; Read pointer |
167 | write_ptr dd ? ; Write pointer |
167 | write_ptr dd ? ; Write pointer |
168 | size dd ? ; Number of bytes buffered |
168 | size dd ? ; Number of bytes buffered |
169 | 169 | ||
170 | ends |
170 | ends |
171 | 171 | ||
172 | struct STREAM_SOCKET TCP_SOCKET |
172 | struct STREAM_SOCKET TCP_SOCKET |
173 | 173 | ||
174 | rcv RING_BUFFER |
174 | rcv RING_BUFFER |
175 | snd RING_BUFFER |
175 | snd RING_BUFFER |
176 | 176 | ||
177 | ends |
177 | ends |
178 | 178 | ||
179 | struct socket_queue_entry |
179 | struct socket_queue_entry |
180 | 180 | ||
181 | data_ptr dd ? |
181 | data_ptr dd ? |
182 | buf_ptr dd ? |
182 | buf_ptr dd ? |
183 | data_size dd ? |
183 | data_size dd ? |
184 | 184 | ||
185 | ends |
185 | ends |
186 | 186 | ||
187 | 187 | ||
188 | SOCKETBUFFSIZE = 4096 ; in bytes |
188 | SOCKETBUFFSIZE = 4096 ; in bytes |
189 | 189 | ||
190 | SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket |
190 | SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket |
191 | ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start |
191 | ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start |
192 | SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) |
192 | SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) |
193 | 193 | ||
194 | uglobal |
194 | uglobal |
195 | align 4 |
195 | align 4 |
196 | 196 | ||
197 | net_sockets rd 4 |
197 | net_sockets rd 4 |
198 | last_socket_num dd ? |
198 | last_socket_num dd ? |
199 | last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
199 | last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
200 | last_TCP_port dw ? ; |
200 | last_TCP_port dw ? ; |
201 | socket_mutex MUTEX |
201 | socket_mutex MUTEX |
202 | 202 | ||
203 | endg |
203 | endg |
204 | 204 | ||
205 | 205 | ||
206 | ;----------------------------------------------------------------- |
206 | ;----------------------------------------------------------------- |
207 | ; |
207 | ; |
208 | ; SOCKET_init |
208 | ; SOCKET_init |
209 | ; |
209 | ; |
210 | ;----------------------------------------------------------------- |
210 | ;----------------------------------------------------------------- |
211 | macro SOCKET_init { |
211 | macro SOCKET_init { |
212 | 212 | ||
213 | xor eax, eax |
213 | xor eax, eax |
214 | mov edi, net_sockets |
214 | mov edi, net_sockets |
215 | mov ecx, 5 |
215 | mov ecx, 5 |
216 | rep stosd |
216 | rep stosd |
217 | 217 | ||
218 | @@: |
218 | @@: |
219 | pseudo_random eax |
219 | pseudo_random eax |
220 | cmp ax, EPHEMERAL_PORT_MIN |
220 | cmp ax, EPHEMERAL_PORT_MIN |
221 | jb @r |
221 | jb @r |
222 | cmp ax, EPHEMERAL_PORT_MAX |
222 | cmp ax, EPHEMERAL_PORT_MAX |
223 | ja @r |
223 | ja @r |
224 | xchg al, ah |
224 | xchg al, ah |
225 | mov [last_UDP_port], ax |
225 | mov [last_UDP_port], ax |
226 | 226 | ||
227 | @@: |
227 | @@: |
228 | pseudo_random eax |
228 | pseudo_random eax |
229 | cmp ax, EPHEMERAL_PORT_MIN |
229 | cmp ax, EPHEMERAL_PORT_MIN |
230 | jb @r |
230 | jb @r |
231 | cmp ax, EPHEMERAL_PORT_MAX |
231 | cmp ax, EPHEMERAL_PORT_MAX |
232 | ja @r |
232 | ja @r |
233 | xchg al, ah |
233 | xchg al, ah |
234 | mov [last_TCP_port], ax |
234 | mov [last_TCP_port], ax |
235 | 235 | ||
236 | mov ecx, socket_mutex |
236 | mov ecx, socket_mutex |
237 | call mutex_init |
237 | call mutex_init |
238 | 238 | ||
239 | } |
239 | } |
240 | 240 | ||
241 | ;----------------------------------------------------------------- |
241 | ;----------------------------------------------------------------- |
242 | ; |
242 | ; |
243 | ; Socket API (function 74) |
243 | ; Socket API (function 74) |
244 | ; |
244 | ; |
245 | ;----------------------------------------------------------------- |
245 | ;----------------------------------------------------------------- |
246 | align 4 |
246 | align 4 |
247 | sys_socket: |
247 | sys_socket: |
248 | 248 | ||
249 | mov dword[esp+20], 0 ; Set error code to 0 |
249 | mov dword[esp+20], 0 ; Set error code to 0 |
250 | 250 | ||
251 | cmp ebx, 255 |
251 | cmp ebx, 255 |
252 | jz SOCKET_debug |
252 | jz SOCKET_debug |
253 | 253 | ||
254 | cmp ebx, .number |
254 | cmp ebx, .number |
255 | ja .error |
255 | ja .error |
256 | jmp dword [.table + 4*ebx] |
256 | jmp dword [.table + 4*ebx] |
257 | 257 | ||
258 | .table: |
258 | .table: |
259 | dd SOCKET_open ; 0 |
259 | dd SOCKET_open ; 0 |
260 | dd SOCKET_close ; 1 |
260 | dd SOCKET_close ; 1 |
261 | dd SOCKET_bind ; 2 |
261 | dd SOCKET_bind ; 2 |
262 | dd SOCKET_listen ; 3 |
262 | dd SOCKET_listen ; 3 |
263 | dd SOCKET_connect ; 4 |
263 | dd SOCKET_connect ; 4 |
264 | dd SOCKET_accept ; 5 |
264 | dd SOCKET_accept ; 5 |
265 | dd SOCKET_send ; 6 |
265 | dd SOCKET_send ; 6 |
266 | dd SOCKET_receive ; 7 |
266 | dd SOCKET_receive ; 7 |
267 | dd SOCKET_set_opt ; 8 |
267 | dd SOCKET_set_opt ; 8 |
268 | dd SOCKET_get_opt ; 9 |
268 | dd SOCKET_get_opt ; 9 |
269 | dd SOCKET_pair ; 10 |
269 | dd SOCKET_pair ; 10 |
270 | .number = ($ - .table) / 4 - 1 |
270 | .number = ($ - .table) / 4 - 1 |
271 | 271 | ||
272 | .error: |
272 | .error: |
273 | mov dword[esp+32], -1 |
273 | mov dword[esp+32], -1 |
274 | mov dword[esp+20], EINVAL |
274 | mov dword[esp+20], EINVAL |
275 | 275 | ||
276 | ret |
276 | ret |
277 | 277 | ||
278 | ;----------------------------------------------------------------- |
278 | ;----------------------------------------------------------------- |
279 | ; |
279 | ; |
280 | ; SOCKET_open |
280 | ; SOCKET_open |
281 | ; |
281 | ; |
282 | ; IN: domain in ecx |
282 | ; IN: domain in ecx |
283 | ; type in edx |
283 | ; type in edx |
284 | ; protocol in esi |
284 | ; protocol in esi |
285 | ; OUT: eax is socket num, -1 on error |
285 | ; OUT: eax is socket num, -1 on error |
286 | ; |
286 | ; |
287 | ;----------------------------------------------------------------- |
287 | ;----------------------------------------------------------------- |
288 | align 4 |
288 | align 4 |
289 | SOCKET_open: |
289 | SOCKET_open: |
290 | 290 | ||
291 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_open: domain=%u type=%u protocol=%x ", ecx, edx, esi |
291 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_open: domain=%u type=%u protocol=%x ", ecx, edx, esi |
292 | 292 | ||
293 | push ecx edx esi |
293 | push ecx edx esi |
294 | call SOCKET_alloc |
294 | call SOCKET_alloc |
295 | pop esi edx ecx |
295 | pop esi edx ecx |
- | 296 | test eax, eax |
|
296 | jz .nobuffs |
297 | jz .nobuffs |
297 | 298 | ||
298 | mov [esp+32], edi ; return socketnumber |
299 | mov [esp+32], edi ; return socketnumber |
299 | DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi |
300 | DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi |
300 | 301 | ||
301 | test edx, SO_NONBLOCK |
302 | test edx, SO_NONBLOCK |
302 | jz @f |
303 | jz @f |
303 | or [eax + SOCKET.options], SO_NONBLOCK |
304 | or [eax + SOCKET.options], SO_NONBLOCK |
304 | and edx, not SO_NONBLOCK |
305 | and edx, not SO_NONBLOCK |
305 | @@: |
306 | @@: |
306 | 307 | ||
307 | mov [eax + SOCKET.Domain], ecx |
308 | mov [eax + SOCKET.Domain], ecx |
308 | mov [eax + SOCKET.Type], edx |
309 | mov [eax + SOCKET.Type], edx |
309 | mov [eax + SOCKET.Protocol], esi |
310 | mov [eax + SOCKET.Protocol], esi |
310 | mov [eax + SOCKET.connect_proc], connect_notsupp |
311 | mov [eax + SOCKET.connect_proc], connect_notsupp |
311 | 312 | ||
312 | cmp ecx, AF_INET4 |
313 | cmp ecx, AF_INET4 |
313 | jne .no_inet4 |
314 | jne .no_inet4 |
314 | 315 | ||
315 | cmp edx, SOCK_DGRAM |
316 | cmp edx, SOCK_DGRAM |
316 | je .udp |
317 | je .udp |
317 | 318 | ||
318 | cmp edx, SOCK_STREAM |
319 | cmp edx, SOCK_STREAM |
319 | je .tcp |
320 | je .tcp |
320 | 321 | ||
321 | cmp edx, SOCK_RAW |
322 | cmp edx, SOCK_RAW |
322 | je .raw |
323 | je .raw |
323 | 324 | ||
324 | .no_inet4: |
325 | .no_inet4: |
325 | cmp ecx, AF_PPP |
326 | cmp ecx, AF_PPP |
326 | jne .no_ppp |
327 | jne .no_ppp |
327 | 328 | ||
328 | cmp esi, PPP_PROTO_ETHERNET |
329 | cmp esi, PPP_PROTO_ETHERNET |
329 | je .pppoe |
330 | je .pppoe |
330 | 331 | ||
331 | .no_ppp: |
332 | .no_ppp: |
332 | .unsupported: |
333 | .unsupported: |
333 | push eax |
334 | push eax |
334 | call SOCKET_free |
335 | call SOCKET_free |
335 | pop eax |
336 | pop eax |
336 | mov dword[esp+20], EOPNOTSUPP |
337 | mov dword[esp+20], EOPNOTSUPP |
337 | mov dword[esp+32], -1 |
338 | mov dword[esp+32], -1 |
338 | ret |
339 | ret |
339 | 340 | ||
340 | .nobuffs: |
341 | .nobuffs: |
341 | mov dword[esp+20], ENOBUFS |
342 | mov dword[esp+20], ENOBUFS |
342 | mov dword[esp+32], -1 |
343 | mov dword[esp+32], -1 |
343 | ret |
344 | ret |
344 | 345 | ||
345 | .raw: |
346 | .raw: |
346 | test esi, esi ; IP_PROTO_IP |
347 | test esi, esi ; IP_PROTO_IP |
347 | jz .raw_ip |
348 | jz .raw_ip |
348 | 349 | ||
349 | cmp esi, IP_PROTO_ICMP |
350 | cmp esi, IP_PROTO_ICMP |
350 | je .raw_icmp |
351 | je .raw_icmp |
351 | 352 | ||
352 | jmp .unsupported |
353 | jmp .unsupported |
353 | 354 | ||
354 | align 4 |
355 | align 4 |
355 | .udp: |
356 | .udp: |
356 | mov [eax + SOCKET.Protocol], IP_PROTO_UDP |
357 | mov [eax + SOCKET.Protocol], IP_PROTO_UDP |
357 | mov [eax + SOCKET.snd_proc], SOCKET_send_udp |
358 | mov [eax + SOCKET.snd_proc], SOCKET_send_udp |
358 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
359 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
359 | mov [eax + SOCKET.connect_proc], UDP_connect |
360 | mov [eax + SOCKET.connect_proc], UDP_connect |
360 | ret |
361 | ret |
361 | 362 | ||
362 | align 4 |
363 | align 4 |
363 | .tcp: |
364 | .tcp: |
364 | mov [eax + SOCKET.Protocol], IP_PROTO_TCP |
365 | mov [eax + SOCKET.Protocol], IP_PROTO_TCP |
365 | mov [eax + SOCKET.snd_proc], SOCKET_send_tcp |
366 | mov [eax + SOCKET.snd_proc], SOCKET_send_tcp |
366 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream |
367 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream |
367 | mov [eax + SOCKET.connect_proc], TCP_connect |
368 | mov [eax + SOCKET.connect_proc], TCP_connect |
368 | 369 | ||
369 | TCP_init_socket eax |
370 | TCP_init_socket eax |
370 | ret |
371 | ret |
371 | 372 | ||
372 | 373 | ||
373 | align 4 |
374 | align 4 |
374 | .raw_ip: |
375 | .raw_ip: |
375 | mov [eax + SOCKET.snd_proc], SOCKET_send_ip |
376 | mov [eax + SOCKET.snd_proc], SOCKET_send_ip |
376 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
377 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
377 | mov [eax + SOCKET.connect_proc], IPv4_connect |
378 | mov [eax + SOCKET.connect_proc], IPv4_connect |
378 | ret |
379 | ret |
379 | 380 | ||
380 | 381 | ||
381 | align 4 |
382 | align 4 |
382 | .raw_icmp: |
383 | .raw_icmp: |
383 | mov [eax + SOCKET.snd_proc], SOCKET_send_icmp |
384 | mov [eax + SOCKET.snd_proc], SOCKET_send_icmp |
384 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
385 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
385 | mov [eax + SOCKET.connect_proc], IPv4_connect |
386 | mov [eax + SOCKET.connect_proc], IPv4_connect |
386 | ret |
387 | ret |
387 | 388 | ||
388 | align 4 |
389 | align 4 |
389 | .pppoe: |
390 | .pppoe: |
390 | push eax |
391 | push eax |
391 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
392 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
392 | pop eax |
393 | pop eax |
393 | 394 | ||
394 | mov [eax + SOCKET.snd_proc], SOCKET_send_pppoe |
395 | mov [eax + SOCKET.snd_proc], SOCKET_send_pppoe |
395 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
396 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
396 | ret |
397 | ret |
397 | 398 | ||
398 | 399 | ||
399 | ;----------------------------------------------------------------- |
400 | ;----------------------------------------------------------------- |
400 | ; |
401 | ; |
401 | ; SOCKET_bind |
402 | ; SOCKET_bind |
402 | ; |
403 | ; |
403 | ; IN: socket number in ecx |
404 | ; IN: socket number in ecx |
404 | ; pointer to sockaddr struct in edx |
405 | ; pointer to sockaddr struct in edx |
405 | ; length of that struct in esi |
406 | ; length of that struct in esi |
406 | ; OUT: 0 on success |
407 | ; OUT: 0 on success |
407 | ; |
408 | ; |
408 | ;----------------------------------------------------------------- |
409 | ;----------------------------------------------------------------- |
409 | align 4 |
410 | align 4 |
410 | SOCKET_bind: |
411 | SOCKET_bind: |
411 | 412 | ||
412 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
413 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
413 | 414 | ||
414 | call SOCKET_num_to_ptr |
415 | call SOCKET_num_to_ptr |
415 | jz .invalid |
416 | jz .invalid |
416 | 417 | ||
417 | cmp esi, 2 |
418 | cmp esi, 2 |
418 | jb .invalid |
419 | jb .invalid |
419 | 420 | ||
420 | cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once |
421 | cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once |
421 | jnz .invalid |
422 | jnz .invalid |
422 | 423 | ||
423 | cmp word [edx], AF_INET4 |
424 | cmp word [edx], AF_INET4 |
424 | je .af_inet4 |
425 | je .af_inet4 |
425 | 426 | ||
426 | cmp word [edx], AF_LOCAL |
427 | cmp word [edx], AF_LOCAL |
427 | je .af_local |
428 | je .af_local |
428 | 429 | ||
429 | .notsupp: |
430 | .notsupp: |
430 | mov dword[esp+20], EOPNOTSUPP |
431 | mov dword[esp+20], EOPNOTSUPP |
431 | mov dword[esp+32], -1 |
432 | mov dword[esp+32], -1 |
432 | ret |
433 | ret |
433 | 434 | ||
434 | .invalid: |
435 | .invalid: |
435 | mov dword[esp+20], EINVAL |
436 | mov dword[esp+20], EINVAL |
436 | mov dword[esp+32], -1 |
437 | mov dword[esp+32], -1 |
437 | ret |
438 | ret |
438 | 439 | ||
439 | .af_local: |
440 | .af_local: |
440 | ; TODO: write code here |
441 | ; TODO: write code here |
441 | mov dword[esp+32], 0 |
442 | mov dword[esp+32], 0 |
442 | ret |
443 | ret |
443 | 444 | ||
444 | .af_inet4: |
445 | .af_inet4: |
445 | cmp esi, 6 |
446 | cmp esi, 6 |
446 | jb .invalid |
447 | jb .invalid |
447 | 448 | ||
448 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
449 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
449 | je .udp |
450 | je .udp |
450 | 451 | ||
451 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
452 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
452 | je .tcp |
453 | je .tcp |
453 | 454 | ||
454 | jmp .notsupp |
455 | jmp .notsupp |
455 | 456 | ||
456 | .tcp: |
457 | .tcp: |
457 | .udp: |
458 | .udp: |
458 | 459 | ||
459 | pushd [edx + 4] ; First, fill in the IP |
460 | pushd [edx + 4] ; First, fill in the IP |
460 | popd [eax + IP_SOCKET.LocalIP] |
461 | popd [eax + IP_SOCKET.LocalIP] |
461 | 462 | ||
462 | mov bx, [edx + 2] ; Did caller specify a local port? |
463 | mov bx, [edx + 2] ; Did caller specify a local port? |
463 | test bx, bx |
464 | test bx, bx |
464 | jnz .just_check |
465 | jnz .just_check |
465 | call SOCKET_find_port ; Nope, find an ephemeral one |
466 | call SOCKET_find_port ; Nope, find an ephemeral one |
466 | jmp .done |
467 | jmp .done |
467 | 468 | ||
468 | .just_check: |
469 | .just_check: |
469 | call SOCKET_check_port ; Yes, check if it's still available |
470 | call SOCKET_check_port ; Yes, check if it's still available |
470 | jz .addrinuse ; ZF is set by socket_check_port on error |
471 | jz .addrinuse ; ZF is set by socket_check_port on error |
471 | 472 | ||
472 | .done: |
473 | .done: |
473 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\ |
474 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\ |
474 | [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ |
475 | [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ |
475 | [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 |
476 | [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 |
476 | 477 | ||
477 | mov dword[esp+32], 0 |
478 | mov dword[esp+32], 0 |
478 | ret |
479 | ret |
479 | 480 | ||
480 | .addrinuse: |
481 | .addrinuse: |
481 | mov dword[esp+32], -1 |
482 | mov dword[esp+32], -1 |
482 | mov dword[esp+20], EADDRINUSE |
483 | mov dword[esp+20], EADDRINUSE |
483 | ret |
484 | ret |
484 | 485 | ||
485 | 486 | ||
486 | 487 | ||
487 | 488 | ||
488 | ;----------------------------------------------------------------- |
489 | ;----------------------------------------------------------------- |
489 | ; |
490 | ; |
490 | ; SOCKET_connect |
491 | ; SOCKET_connect |
491 | ; |
492 | ; |
492 | ; IN: socket number in ecx |
493 | ; IN: socket number in ecx |
493 | ; pointer to sockaddr struct in edx |
494 | ; pointer to sockaddr struct in edx |
494 | ; length of that struct in esi |
495 | ; length of that struct in esi |
495 | ; OUT: 0 on success |
496 | ; OUT: 0 on success |
496 | ; |
497 | ; |
497 | ;----------------------------------------------------------------- |
498 | ;----------------------------------------------------------------- |
498 | align 4 |
499 | align 4 |
499 | SOCKET_connect: |
500 | SOCKET_connect: |
500 | 501 | ||
501 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
502 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
502 | 503 | ||
503 | call SOCKET_num_to_ptr |
504 | call SOCKET_num_to_ptr |
504 | jz .invalid |
505 | jz .invalid |
505 | 506 | ||
506 | cmp esi, 8 |
507 | cmp esi, 8 |
507 | jb .invalid |
508 | jb .invalid |
508 | 509 | ||
509 | cmp [eax + SOCKET.state], SS_ISCONNECTING |
510 | cmp [eax + SOCKET.state], SS_ISCONNECTING |
510 | je .already |
511 | je .already |
511 | 512 | ||
512 | test [eax + SOCKET.options], SO_ACCEPTCON |
513 | test [eax + SOCKET.options], SO_ACCEPTCON |
513 | jnz .notsupp |
514 | jnz .notsupp |
514 | 515 | ||
515 | call [eax + SOCKET.connect_proc] |
516 | call [eax + SOCKET.connect_proc] |
516 | 517 | ||
517 | mov dword[esp+20], ebx |
518 | mov dword[esp+20], ebx |
518 | mov dword[esp+32], eax |
519 | mov dword[esp+32], eax |
519 | ret |
520 | ret |
520 | 521 | ||
521 | 522 | ||
522 | .notsupp: |
523 | .notsupp: |
523 | mov dword[esp+20], EOPNOTSUPP |
524 | mov dword[esp+20], EOPNOTSUPP |
524 | mov dword[esp+32], -1 |
525 | mov dword[esp+32], -1 |
525 | ret |
526 | ret |
526 | 527 | ||
527 | .invalid: |
528 | .invalid: |
528 | mov dword[esp+20], EINVAL |
529 | mov dword[esp+20], EINVAL |
529 | mov dword[esp+32], -1 |
530 | mov dword[esp+32], -1 |
530 | ret |
531 | ret |
531 | 532 | ||
532 | .already: |
533 | .already: |
533 | mov dword[esp+20], EALREADY |
534 | mov dword[esp+20], EALREADY |
534 | mov dword[esp+32], -1 |
535 | mov dword[esp+32], -1 |
535 | ret |
536 | ret |
536 | 537 | ||
537 | 538 | ||
538 | connect_notsupp: |
539 | connect_notsupp: |
539 | xor eax, eax |
540 | xor eax, eax |
540 | dec eax |
541 | dec eax |
541 | mov ebx, EOPNOTSUPP |
542 | mov ebx, EOPNOTSUPP |
542 | ret |
543 | ret |
543 | 544 | ||
544 | 545 | ||
545 | ;----------------------------------------------------------------- |
546 | ;----------------------------------------------------------------- |
546 | ; |
547 | ; |
547 | ; SOCKET_listen |
548 | ; SOCKET_listen |
548 | ; |
549 | ; |
549 | ; IN: socket number in ecx |
550 | ; IN: socket number in ecx |
550 | ; backlog in edx |
551 | ; backlog in edx |
551 | ; OUT: eax is socket num, -1 on error |
552 | ; OUT: eax is socket num, -1 on error |
552 | ; |
553 | ; |
553 | ;----------------------------------------------------------------- |
554 | ;----------------------------------------------------------------- |
554 | align 4 |
555 | align 4 |
555 | SOCKET_listen: |
556 | SOCKET_listen: |
556 | 557 | ||
557 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx |
558 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx |
558 | 559 | ||
559 | call SOCKET_num_to_ptr |
560 | call SOCKET_num_to_ptr |
560 | jz .invalid |
561 | jz .invalid |
561 | 562 | ||
562 | cmp [eax + SOCKET.Domain], AF_INET4 |
563 | cmp [eax + SOCKET.Domain], AF_INET4 |
563 | jne .notsupp |
564 | jne .notsupp |
564 | 565 | ||
565 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
566 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
566 | jne .invalid |
567 | jne .invalid |
567 | 568 | ||
568 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
569 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
569 | je .already |
570 | je .already |
570 | 571 | ||
571 | cmp [eax + IP_SOCKET.LocalIP], 0 |
572 | cmp [eax + IP_SOCKET.LocalIP], 0 |
572 | jne @f |
573 | jne @f |
573 | push [IP_LIST + 4] ;;; fixme!!!! |
574 | push [IP_LIST + 4] ;;; fixme!!!! |
574 | pop [eax + IP_SOCKET.LocalIP] |
575 | pop [eax + IP_SOCKET.LocalIP] |
575 | @@: |
576 | @@: |
576 | 577 | ||
577 | cmp edx, MAX_backlog |
578 | cmp edx, MAX_backlog |
578 | jbe @f |
579 | jbe @f |
579 | mov edx, MAX_backlog |
580 | mov edx, MAX_backlog |
580 | @@: |
581 | @@: |
581 | 582 | ||
582 | mov [eax + SOCKET.backlog], dx |
583 | mov [eax + SOCKET.backlog], dx |
583 | or [eax + SOCKET.options], SO_ACCEPTCON |
584 | or [eax + SOCKET.options], SO_ACCEPTCON |
584 | mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN |
585 | mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN |
585 | mov [eax + TCP_SOCKET.timer_keepalive], 0 ; disable keepalive timer |
586 | mov [eax + TCP_SOCKET.timer_keepalive], 0 ; disable keepalive timer |
586 | 587 | ||
587 | push eax |
588 | push eax |
588 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue |
589 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue |
589 | pop eax |
590 | pop eax |
590 | 591 | ||
591 | mov dword[esp+32], 0 |
592 | mov dword[esp+32], 0 |
592 | ret |
593 | ret |
593 | 594 | ||
594 | .notsupp: |
595 | .notsupp: |
595 | mov dword[esp+20], EOPNOTSUPP |
596 | mov dword[esp+20], EOPNOTSUPP |
596 | mov dword[esp+32], -1 |
597 | mov dword[esp+32], -1 |
597 | ret |
598 | ret |
598 | 599 | ||
599 | .invalid: |
600 | .invalid: |
600 | mov dword[esp+20], EINVAL |
601 | mov dword[esp+20], EINVAL |
601 | mov dword[esp+32], -1 |
602 | mov dword[esp+32], -1 |
602 | ret |
603 | ret |
603 | 604 | ||
604 | .already: |
605 | .already: |
605 | mov dword[esp+20], EALREADY |
606 | mov dword[esp+20], EALREADY |
606 | mov dword[esp+32], -1 |
607 | mov dword[esp+32], -1 |
607 | ret |
608 | ret |
608 | 609 | ||
609 | 610 | ||
610 | ;----------------------------------------------------------------- |
611 | ;----------------------------------------------------------------- |
611 | ; |
612 | ; |
612 | ; SOCKET_accept |
613 | ; SOCKET_accept |
613 | ; |
614 | ; |
614 | ; IN: socket number in ecx |
615 | ; IN: socket number in ecx |
615 | ; addr in edx |
616 | ; addr in edx |
616 | ; addrlen in esi |
617 | ; addrlen in esi |
617 | ; OUT: eax is socket num, -1 on error |
618 | ; OUT: eax is socket num, -1 on error |
618 | ; |
619 | ; |
619 | ;----------------------------------------------------------------- |
620 | ;----------------------------------------------------------------- |
620 | align 4 |
621 | align 4 |
621 | SOCKET_accept: |
622 | SOCKET_accept: |
622 | 623 | ||
623 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
624 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
624 | 625 | ||
625 | call SOCKET_num_to_ptr |
626 | call SOCKET_num_to_ptr |
626 | jz .invalid |
627 | jz .invalid |
627 | 628 | ||
628 | test [eax + SOCKET.options], SO_ACCEPTCON |
629 | test [eax + SOCKET.options], SO_ACCEPTCON |
629 | jz .invalid |
630 | jz .invalid |
630 | 631 | ||
631 | cmp [eax + SOCKET.Domain], AF_INET4 |
632 | cmp [eax + SOCKET.Domain], AF_INET4 |
632 | jne .notsupp |
633 | jne .notsupp |
633 | 634 | ||
634 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
635 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
635 | jne .invalid |
636 | jne .invalid |
636 | 637 | ||
637 | .loop: |
638 | .loop: |
638 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block |
639 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block |
639 | 640 | ||
640 | ; Ok, we got a socket ptr |
641 | ; Ok, we got a socket ptr |
641 | mov eax, [esi] |
642 | mov eax, [esi] |
642 | 643 | ||
643 | ; Change thread ID to that of the current thread |
644 | ; Change thread ID to that of the current thread |
644 | mov ebx, [TASK_BASE] |
645 | mov ebx, [TASK_BASE] |
645 | mov ebx, [ebx + TASKDATA.pid] |
646 | mov ebx, [ebx + TASKDATA.pid] |
646 | mov [eax + SOCKET.TID], ebx |
647 | mov [eax + SOCKET.TID], ebx |
647 | 648 | ||
648 | ; Convert it to a socket number |
649 | ; Convert it to a socket number |
649 | call SOCKET_ptr_to_num |
650 | call SOCKET_ptr_to_num |
650 | jz .invalid ; FIXME ? |
651 | jz .invalid ; FIXME ? |
651 | 652 | ||
652 | ; and return it to caller |
653 | ; and return it to caller |
653 | mov [esp+32], eax |
654 | mov [esp+32], eax |
654 | ret |
655 | ret |
655 | 656 | ||
656 | .block: |
657 | .block: |
657 | test [eax + SOCKET.options], SO_NONBLOCK |
658 | test [eax + SOCKET.options], SO_NONBLOCK |
658 | jnz .wouldblock |
659 | jnz .wouldblock |
659 | 660 | ||
660 | call SOCKET_block |
661 | call SOCKET_block |
661 | jmp .loop |
662 | jmp .loop |
662 | 663 | ||
663 | .wouldblock: |
664 | .wouldblock: |
664 | mov dword[esp+20], EWOULDBLOCK |
665 | mov dword[esp+20], EWOULDBLOCK |
665 | mov dword[esp+32], -1 |
666 | mov dword[esp+32], -1 |
666 | ret |
667 | ret |
667 | 668 | ||
668 | .invalid: |
669 | .invalid: |
669 | mov dword[esp+20], EINVAL |
670 | mov dword[esp+20], EINVAL |
670 | mov dword[esp+32], -1 |
671 | mov dword[esp+32], -1 |
671 | ret |
672 | ret |
672 | 673 | ||
673 | .notsupp: |
674 | .notsupp: |
674 | mov dword[esp+20], EOPNOTSUPP |
675 | mov dword[esp+20], EOPNOTSUPP |
675 | mov dword[esp+32], -1 |
676 | mov dword[esp+32], -1 |
676 | ret |
677 | ret |
677 | 678 | ||
678 | ;----------------------------------------------------------------- |
679 | ;----------------------------------------------------------------- |
679 | ; |
680 | ; |
680 | ; SOCKET_close |
681 | ; SOCKET_close |
681 | ; |
682 | ; |
682 | ; IN: socket number in ecx |
683 | ; IN: socket number in ecx |
683 | ; OUT: eax is socket num, -1 on error |
684 | ; OUT: eax is socket num, -1 on error |
684 | ; |
685 | ; |
685 | ;----------------------------------------------------------------- |
686 | ;----------------------------------------------------------------- |
686 | align 4 |
687 | align 4 |
687 | SOCKET_close: |
688 | SOCKET_close: |
688 | 689 | ||
689 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx |
690 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx |
690 | 691 | ||
691 | call SOCKET_num_to_ptr |
692 | call SOCKET_num_to_ptr |
692 | jz .invalid |
693 | jz .invalid |
693 | 694 | ||
694 | mov dword[esp+32], 0 ; The socket exists, so we will succeed in closing it. |
695 | mov dword[esp+32], 0 ; The socket exists, so we will succeed in closing it. |
695 | 696 | ||
696 | or [eax + SOCKET.options], SO_NONBLOCK ; Mark the socket as non blocking, we dont want it to block any longer! |
697 | or [eax + SOCKET.options], SO_NONBLOCK ; Mark the socket as non blocking, we dont want it to block any longer! |
697 | 698 | ||
698 | test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state? |
699 | test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state? |
699 | jz @f |
700 | jz @f |
700 | call SOCKET_notify.unblock ; Unblock it. |
701 | call SOCKET_notify ; Unblock it. |
701 | @@: |
702 | @@: |
702 | 703 | ||
703 | cmp [eax + SOCKET.Domain], AF_INET4 |
704 | cmp [eax + SOCKET.Domain], AF_INET4 |
704 | jne .free |
705 | jne .free |
705 | 706 | ||
706 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
707 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
707 | je .tcp |
708 | je .tcp |
708 | 709 | ||
709 | .free: |
710 | .free: |
710 | call SOCKET_free |
711 | call SOCKET_free |
711 | ret |
712 | ret |
712 | 713 | ||
713 | .tcp: |
714 | .tcp: |
714 | 715 | ||
715 | call TCP_usrclosed |
716 | call TCP_usrclosed |
716 | 717 | ||
717 | test eax, eax |
718 | test eax, eax |
718 | jz @f |
719 | jz @f |
719 | call TCP_output ; If connection is not closed yet, send the FIN |
720 | call TCP_output ; If connection is not closed yet, send the FIN |
720 | @@: |
721 | @@: |
721 | 722 | ||
722 | ret |
723 | ret |
723 | 724 | ||
724 | 725 | ||
725 | .invalid: |
726 | .invalid: |
726 | mov dword[esp+20], EINVAL |
727 | mov dword[esp+20], EINVAL |
727 | mov dword[esp+32], -1 |
728 | mov dword[esp+32], -1 |
728 | ret |
729 | ret |
729 | 730 | ||
730 | 731 | ||
731 | ;----------------------------------------------------------------- |
732 | ;----------------------------------------------------------------- |
732 | ; |
733 | ; |
733 | ; SOCKET_receive |
734 | ; SOCKET_receive |
734 | ; |
735 | ; |
735 | ; IN: socket number in ecx |
736 | ; IN: socket number in ecx |
736 | ; addr to buffer in edx |
737 | ; addr to buffer in edx |
737 | ; length of buffer in esi |
738 | ; length of buffer in esi |
738 | ; flags in edi |
739 | ; flags in edi |
739 | ; OUT: eax is number of bytes copied, -1 on error |
740 | ; OUT: eax is number of bytes copied, -1 on error |
740 | ; |
741 | ; |
741 | ;----------------------------------------------------------------- |
742 | ;----------------------------------------------------------------- |
742 | align 4 |
743 | align 4 |
743 | SOCKET_receive: |
744 | SOCKET_receive: |
744 | 745 | ||
745 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi |
746 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi |
746 | 747 | ||
747 | call SOCKET_num_to_ptr |
748 | call SOCKET_num_to_ptr |
748 | jz .invalid |
749 | jz .invalid |
749 | 750 | ||
750 | .loop: |
751 | .loop: |
751 | push edi |
752 | push edi |
752 | call [eax + SOCKET.rcv_proc] |
753 | call [eax + SOCKET.rcv_proc] |
753 | pop edi |
754 | pop edi |
754 | 755 | ||
755 | test [eax + SOCKET.state], SS_CANTRCVMORE |
756 | test [eax + SOCKET.state], SS_CANTRCVMORE |
756 | jnz .return |
757 | jnz .return |
757 | 758 | ||
758 | cmp ebx, EWOULDBLOCK |
759 | cmp ebx, EWOULDBLOCK |
759 | jne .return |
760 | jne .return |
760 | 761 | ||
761 | test edi, MSG_DONTWAIT |
762 | test edi, MSG_DONTWAIT |
762 | jnz .return_err |
763 | jnz .return_err |
763 | 764 | ||
764 | ; test [eax + SOCKET.options], SO_NONBLOCK |
765 | ; test [eax + SOCKET.options], SO_NONBLOCK |
765 | ; jnz .return_err |
766 | ; jnz .return_err |
766 | 767 | ||
767 | call SOCKET_block |
768 | call SOCKET_block |
768 | jmp .loop |
769 | jmp .loop |
769 | 770 | ||
770 | 771 | ||
771 | .invalid: |
772 | .invalid: |
772 | push EINVAL |
773 | push EINVAL |
773 | pop ebx |
774 | pop ebx |
774 | .return_err: |
775 | .return_err: |
775 | mov ecx, -1 |
776 | mov ecx, -1 |
776 | .return: |
777 | .return: |
777 | mov [esp+20], ebx |
778 | mov [esp+20], ebx |
778 | mov [esp+32], ecx |
779 | mov [esp+32], ecx |
779 | ret |
780 | ret |
780 | 781 | ||
781 | 782 | ||
782 | 783 | ||
783 | 784 | ||
784 | 785 | ||
785 | align 4 |
786 | align 4 |
786 | SOCKET_receive_dgram: |
787 | SOCKET_receive_dgram: |
787 | 788 | ||
788 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n" |
789 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n" |
789 | 790 | ||
790 | mov ebx, esi ; bufferlength |
791 | mov ebx, esi ; bufferlength |
791 | 792 | ||
792 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success. |
793 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success. |
793 | mov ecx, [esi + socket_queue_entry.data_size] |
794 | mov ecx, [esi + socket_queue_entry.data_size] |
794 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: %u bytes data\n", ecx |
795 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: %u bytes data\n", ecx |
795 | 796 | ||
796 | cmp ecx, ebx ; If data segment does not fit in applications buffer, abort |
797 | cmp ecx, ebx ; If data segment does not fit in applications buffer, abort |
797 | ja .too_small |
798 | ja .too_small |
798 | 799 | ||
799 | push eax ecx |
800 | push eax ecx |
800 | push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later |
801 | push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later |
801 | mov esi, [esi + socket_queue_entry.data_ptr] |
802 | mov esi, [esi + socket_queue_entry.data_ptr] |
802 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi |
803 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi |
803 | 804 | ||
804 | ; copy the data from kernel buffer to application buffer |
805 | ; copy the data from kernel buffer to application buffer |
805 | mov edi, edx ; bufferaddr |
806 | mov edi, edx ; bufferaddr |
806 | shr ecx, 1 |
807 | shr ecx, 1 |
807 | jnc .nb |
808 | jnc .nb |
808 | movsb |
809 | movsb |
809 | .nb: |
810 | .nb: |
810 | shr ecx, 1 |
811 | shr ecx, 1 |
811 | jnc .nw |
812 | jnc .nw |
812 | movsw |
813 | movsw |
813 | .nw: |
814 | .nw: |
814 | test ecx, ecx |
815 | test ecx, ecx |
815 | jz .nd |
816 | jz .nd |
816 | rep movsd |
817 | rep movsd |
817 | .nd: |
818 | .nd: |
818 | 819 | ||
819 | call NET_packet_free |
820 | call NET_packet_free |
820 | pop ecx eax ; return number of bytes copied to application |
821 | pop ecx eax ; return number of bytes copied to application |
821 | xor ebx, ebx |
822 | xor ebx, ebx |
822 | ret |
823 | ret |
823 | 824 | ||
824 | .too_small: |
825 | .too_small: |
825 | mov ecx, -1 |
826 | mov ecx, -1 |
826 | push EMSGSIZE |
827 | push EMSGSIZE |
827 | pop ebx |
828 | pop ebx |
828 | ret |
829 | ret |
829 | 830 | ||
830 | .wouldblock: |
831 | .wouldblock: |
831 | push EWOULDBLOCK |
832 | push EWOULDBLOCK |
832 | pop ebx |
833 | pop ebx |
833 | ret |
834 | ret |
834 | 835 | ||
835 | 836 | ||
836 | 837 | ||
837 | align 4 |
838 | align 4 |
838 | SOCKET_receive_local: |
839 | SOCKET_receive_local: |
839 | 840 | ||
840 | ; does this socket have a PID yet? |
841 | ; does this socket have a PID yet? |
841 | cmp [eax + SOCKET.PID], 0 |
842 | cmp [eax + SOCKET.PID], 0 |
842 | jne @f |
843 | jne @f |
843 | 844 | ||
844 | ; Change PID to that of current process |
845 | ; Change PID to that of current process |
845 | mov ebx, [TASK_BASE] |
846 | mov ebx, [TASK_BASE] |
846 | mov ebx, [ebx + TASKDATA.pid] |
847 | mov ebx, [ebx + TASKDATA.pid] |
847 | mov [eax + SOCKET.PID], ebx |
848 | mov [eax + SOCKET.PID], ebx |
848 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
849 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
849 | @@: |
850 | @@: |
850 | 851 | ||
851 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream |
852 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream |
852 | 853 | ||
853 | ; ... continue to SOCKET_receive_stream |
854 | ; ... continue to SOCKET_receive_stream |
854 | 855 | ||
855 | align 4 |
856 | align 4 |
856 | SOCKET_receive_stream: |
857 | SOCKET_receive_stream: |
857 | 858 | ||
858 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: STREAM\n" |
859 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: STREAM\n" |
859 | 860 | ||
860 | cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0 |
861 | cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0 |
861 | je .wouldblock |
862 | je .wouldblock |
862 | 863 | ||
863 | test edi, MSG_PEEK |
864 | test edi, MSG_PEEK |
864 | jnz .peek |
865 | jnz .peek |
865 | 866 | ||
866 | mov ecx, esi |
867 | mov ecx, esi |
867 | mov edi, edx |
868 | mov edi, edx |
868 | xor edx, edx |
869 | xor edx, edx |
869 | 870 | ||
870 | push eax |
871 | push eax |
871 | add eax, STREAM_SOCKET.rcv |
872 | add eax, STREAM_SOCKET.rcv |
872 | call SOCKET_ring_read ; copy data from kernel buffer to application buffer |
873 | call SOCKET_ring_read ; copy data from kernel buffer to application buffer |
873 | call SOCKET_ring_free ; free read memory |
874 | call SOCKET_ring_free ; free read memory |
874 | pop eax |
875 | pop eax |
875 | 876 | ||
876 | xor ebx, ebx ; errorcode = 0 (no error) |
877 | xor ebx, ebx ; errorcode = 0 (no error) |
877 | ret |
878 | ret |
878 | 879 | ||
879 | .wouldblock: |
880 | .wouldblock: |
880 | push EWOULDBLOCK |
881 | push EWOULDBLOCK |
881 | pop ebx |
882 | pop ebx |
882 | xor ecx, ecx |
883 | xor ecx, ecx |
883 | ret |
884 | ret |
884 | 885 | ||
885 | .peek: |
886 | .peek: |
886 | mov ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size] |
887 | mov ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size] |
887 | xor ebx, ebx |
888 | xor ebx, ebx |
888 | ret |
889 | ret |
889 | 890 | ||
890 | 891 | ||
891 | ;----------------------------------------------------------------- |
892 | ;----------------------------------------------------------------- |
892 | ; |
893 | ; |
893 | ; SOCKET_send |
894 | ; SOCKET_send |
894 | ; |
895 | ; |
895 | ; |
896 | ; |
896 | ; IN: socket number in ecx |
897 | ; IN: socket number in ecx |
897 | ; pointer to data in edx |
898 | ; pointer to data in edx |
898 | ; datalength in esi |
899 | ; datalength in esi |
899 | ; flags in edi |
900 | ; flags in edi |
900 | ; OUT: -1 on error |
901 | ; OUT: -1 on error |
901 | ; |
902 | ; |
902 | ;----------------------------------------------------------------- |
903 | ;----------------------------------------------------------------- |
903 | align 4 |
904 | align 4 |
904 | SOCKET_send: |
905 | SOCKET_send: |
905 | 906 | ||
906 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi |
907 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi |
907 | 908 | ||
908 | call SOCKET_num_to_ptr |
909 | call SOCKET_num_to_ptr |
909 | jz .invalid |
910 | jz .invalid |
910 | 911 | ||
911 | mov ecx, esi |
912 | mov ecx, esi |
912 | mov esi, edx |
913 | mov esi, edx |
913 | 914 | ||
914 | jmp [eax + SOCKET.snd_proc] |
915 | jmp [eax + SOCKET.snd_proc] |
915 | 916 | ||
916 | .invalid: |
917 | .invalid: |
917 | mov dword[esp+20], EINVAL |
918 | mov dword[esp+20], EINVAL |
918 | mov dword[esp+32], -1 |
919 | mov dword[esp+32], -1 |
919 | ret |
920 | ret |
920 | 921 | ||
921 | 922 | ||
922 | align 4 |
923 | align 4 |
923 | SOCKET_send_udp: |
924 | SOCKET_send_udp: |
924 | 925 | ||
925 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: UDP\n" |
926 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: UDP\n" |
926 | 927 | ||
927 | mov [esp+32], ecx |
928 | mov [esp+32], ecx |
928 | call UDP_output |
929 | call UDP_output |
929 | cmp eax, -1 |
930 | cmp eax, -1 |
930 | je .error |
931 | je .error |
931 | ret |
932 | ret |
932 | 933 | ||
933 | .error: |
934 | .error: |
934 | mov dword[esp+32], -1 |
935 | mov dword[esp+32], -1 |
935 | mov dword[esp+20], EMSGSIZE ; FIXME: UDP_output should return error codes! |
936 | mov dword[esp+20], EMSGSIZE ; FIXME: UDP_output should return error codes! |
936 | ret |
937 | ret |
937 | 938 | ||
938 | 939 | ||
939 | align 4 |
940 | align 4 |
940 | SOCKET_send_tcp: |
941 | SOCKET_send_tcp: |
941 | 942 | ||
942 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP\n" |
943 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP\n" |
943 | 944 | ||
944 | push eax |
945 | push eax |
945 | add eax, STREAM_SOCKET.snd |
946 | add eax, STREAM_SOCKET.snd |
946 | call SOCKET_ring_write |
947 | call SOCKET_ring_write |
947 | pop eax |
948 | pop eax |
948 | 949 | ||
949 | mov [esp+32], ecx |
950 | mov [esp+32], ecx |
950 | mov [eax + SOCKET.errorcode], 0 |
951 | mov [eax + SOCKET.errorcode], 0 |
951 | push eax |
952 | push eax |
952 | call TCP_output ; FIXME: this doesnt look pretty, does it? |
953 | call TCP_output ; FIXME: this doesnt look pretty, does it? |
953 | pop eax |
954 | pop eax |
954 | mov eax, [eax + SOCKET.errorcode] |
955 | mov eax, [eax + SOCKET.errorcode] |
955 | mov [esp+20], eax |
956 | mov [esp+20], eax |
956 | ret |
957 | ret |
957 | 958 | ||
958 | 959 | ||
959 | align 4 |
960 | align 4 |
960 | SOCKET_send_ip: |
961 | SOCKET_send_ip: |
961 | 962 | ||
962 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n" |
963 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n" |
963 | 964 | ||
964 | mov [esp+32], ecx |
965 | mov [esp+32], ecx |
965 | call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes! |
966 | call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes! |
966 | cmp eax, -1 |
967 | cmp eax, -1 |
967 | je .error |
968 | je .error |
968 | ret |
969 | ret |
969 | 970 | ||
970 | .error: |
971 | .error: |
971 | mov dword[esp+32], -1 |
972 | mov dword[esp+32], -1 |
972 | mov dword[esp+20], EMSGSIZE |
973 | mov dword[esp+20], EMSGSIZE |
973 | ret |
974 | ret |
974 | 975 | ||
975 | 976 | ||
976 | align 4 |
977 | align 4 |
977 | SOCKET_send_icmp: |
978 | SOCKET_send_icmp: |
978 | 979 | ||
979 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n" |
980 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n" |
980 | 981 | ||
981 | mov [esp+32], ecx |
982 | mov [esp+32], ecx |
982 | call ICMP_output_raw ; FIXME: errorcodes |
983 | call ICMP_output_raw ; FIXME: errorcodes |
983 | cmp eax, -1 |
984 | cmp eax, -1 |
984 | je .error |
985 | je .error |
985 | ret |
986 | ret |
986 | 987 | ||
987 | .error: |
988 | .error: |
988 | mov dword[esp+32], -1 |
989 | mov dword[esp+32], -1 |
989 | mov dword[esp+20], EMSGSIZE |
990 | mov dword[esp+20], EMSGSIZE |
990 | ret |
991 | ret |
991 | 992 | ||
992 | 993 | ||
993 | align 4 |
994 | align 4 |
994 | SOCKET_send_pppoe: |
995 | SOCKET_send_pppoe: |
995 | 996 | ||
996 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: PPPoE\n" |
997 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: PPPoE\n" |
997 | 998 | ||
998 | mov [esp+32], ecx |
999 | mov [esp+32], ecx |
999 | mov ebx, [eax + SOCKET.device] |
1000 | mov ebx, [eax + SOCKET.device] |
1000 | 1001 | ||
1001 | call PPPoE_discovery_output ; FIXME: errorcodes |
1002 | call PPPoE_discovery_output ; FIXME: errorcodes |
1002 | cmp eax, -1 |
1003 | cmp eax, -1 |
1003 | je .error |
1004 | je .error |
1004 | ret |
1005 | ret |
1005 | 1006 | ||
1006 | .error: |
1007 | .error: |
1007 | mov dword[esp+32], -1 |
1008 | mov dword[esp+32], -1 |
1008 | mov dword[esp+20], EMSGSIZE |
1009 | mov dword[esp+20], EMSGSIZE |
1009 | ret |
1010 | ret |
1010 | 1011 | ||
1011 | 1012 | ||
1012 | 1013 | ||
1013 | align 4 |
1014 | align 4 |
1014 | SOCKET_send_local: |
1015 | SOCKET_send_local: |
1015 | 1016 | ||
1016 | ; does this socket have a PID yet? |
1017 | ; does this socket have a PID yet? |
1017 | cmp [eax + SOCKET.PID], 0 |
1018 | cmp [eax + SOCKET.PID], 0 |
1018 | jne @f |
1019 | jne @f |
1019 | 1020 | ||
1020 | ; Change PID to that of current process |
1021 | ; Change PID to that of current process |
1021 | mov ebx, [TASK_BASE] |
1022 | mov ebx, [TASK_BASE] |
1022 | mov ebx, [ebx + TASKDATA.pid] |
1023 | mov ebx, [ebx + TASKDATA.pid] |
1023 | mov [eax + SOCKET.PID], ebx |
1024 | mov [eax + SOCKET.PID], ebx |
1024 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1025 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1025 | @@: |
1026 | @@: |
1026 | mov [eax + SOCKET.snd_proc], SOCKET_send_local_ |
1027 | mov [eax + SOCKET.snd_proc], SOCKET_send_local_ |
1027 | 1028 | ||
1028 | align 4 |
1029 | align 4 |
1029 | SOCKET_send_local_: |
1030 | SOCKET_send_local_: |
1030 | 1031 | ||
1031 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: LOCAL\n" |
1032 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: LOCAL\n" |
1032 | 1033 | ||
1033 | ; get the other side's socket and check if it still exists |
1034 | ; get the other side's socket and check if it still exists |
1034 | mov eax, [eax + SOCKET.device] |
1035 | mov eax, [eax + SOCKET.device] |
1035 | call SOCKET_check |
1036 | call SOCKET_check |
1036 | jz .invalid |
1037 | jz .invalid |
1037 | 1038 | ||
1038 | ; allright, shove in the data! |
1039 | ; allright, shove in the data! |
1039 | push eax |
1040 | push eax |
1040 | add eax, STREAM_SOCKET.rcv |
1041 | add eax, STREAM_SOCKET.rcv |
1041 | call SOCKET_ring_write |
1042 | call SOCKET_ring_write |
1042 | pop eax |
1043 | pop eax |
1043 | 1044 | ||
1044 | ; return the number of written bytes (or errorcode) to application |
1045 | ; return the number of written bytes (or errorcode) to application |
1045 | mov [esp+32], ecx |
1046 | mov [esp+32], ecx |
1046 | 1047 | ||
1047 | ; and notify the other end |
1048 | ; and notify the other end |
1048 | call SOCKET_notify |
1049 | call SOCKET_notify |
1049 | 1050 | ||
1050 | ret |
1051 | ret |
1051 | 1052 | ||
1052 | .invalid: |
1053 | .invalid: |
1053 | mov dword[esp+32], -1 |
1054 | mov dword[esp+32], -1 |
1054 | mov dword[esp+20], EINVAL |
1055 | mov dword[esp+20], EINVAL |
1055 | ret |
1056 | ret |
1056 | 1057 | ||
1057 | 1058 | ||
1058 | ;----------------------------------------------------------------- |
1059 | ;----------------------------------------------------------------- |
1059 | ; |
1060 | ; |
1060 | ; SOCKET_get_options |
1061 | ; SOCKET_get_options |
1061 | ; |
1062 | ; |
1062 | ; IN: ecx = socket number |
1063 | ; IN: ecx = socket number |
1063 | ; edx = pointer to the options: |
1064 | ; edx = pointer to the options: |
1064 | ; dd level, optname, optval, optlen |
1065 | ; dd level, optname, optval, optlen |
1065 | ; OUT: -1 on error |
1066 | ; OUT: -1 on error |
1066 | ; |
1067 | ; |
1067 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
1068 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
1068 | ; TODO: find best way to notify that send()'ed data were acknowledged |
1069 | ; TODO: find best way to notify that send()'ed data were acknowledged |
1069 | ; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*. |
1070 | ; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*. |
1070 | ; |
1071 | ; |
1071 | ;----------------------------------------------------------------- |
1072 | ;----------------------------------------------------------------- |
1072 | align 4 |
1073 | align 4 |
1073 | SOCKET_get_opt: |
1074 | SOCKET_get_opt: |
1074 | 1075 | ||
1075 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n" |
1076 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n" |
1076 | 1077 | ||
1077 | call SOCKET_num_to_ptr |
1078 | call SOCKET_num_to_ptr |
1078 | jz .invalid |
1079 | jz .invalid |
1079 | 1080 | ||
1080 | cmp dword [edx], IP_PROTO_TCP |
1081 | cmp dword [edx], IP_PROTO_TCP |
1081 | jne .invalid |
1082 | jne .invalid |
1082 | cmp dword [edx+4], -2 |
1083 | cmp dword [edx+4], -2 |
1083 | je @f |
1084 | je @f |
1084 | cmp dword [edx+4], -3 |
1085 | cmp dword [edx+4], -3 |
1085 | jne .invalid |
1086 | jne .invalid |
1086 | @@: |
1087 | @@: |
1087 | ; mov eax, [edx+12] |
1088 | ; mov eax, [edx+12] |
1088 | ; test eax, eax |
1089 | ; test eax, eax |
1089 | ; jz .fail |
1090 | ; jz .fail |
1090 | ; cmp dword [eax], 4 |
1091 | ; cmp dword [eax], 4 |
1091 | ; mov dword [eax], 4 |
1092 | ; mov dword [eax], 4 |
1092 | ; jb .fail |
1093 | ; jb .fail |
1093 | ; stdcall net_socket_num_to_addr, ecx |
1094 | ; stdcall net_socket_num_to_addr, ecx |
1094 | ; test eax, eax |
1095 | ; test eax, eax |
1095 | ; jz .fail |
1096 | ; jz .fail |
1096 | ; ; todo: check that eax is really TCP socket |
1097 | ; ; todo: check that eax is really TCP socket |
1097 | ; mov ecx, [eax + TCP_SOCKET.last_ack_number] |
1098 | ; mov ecx, [eax + TCP_SOCKET.last_ack_number] |
1098 | ; cmp dword [edx+4], -2 |
1099 | ; cmp dword [edx+4], -2 |
1099 | ; jz @f |
1100 | ; jz @f |
1100 | ; mov ecx, [eax + TCP_SOCKET.state] |
1101 | ; mov ecx, [eax + TCP_SOCKET.state] |
1101 | @@: |
1102 | @@: |
1102 | mov eax, [edx+8] |
1103 | mov eax, [edx+8] |
1103 | test eax, eax |
1104 | test eax, eax |
1104 | jz @f |
1105 | jz @f |
1105 | mov [eax], ecx |
1106 | mov [eax], ecx |
1106 | @@: |
1107 | @@: |
1107 | mov dword [esp+32], 0 |
1108 | mov dword [esp+32], 0 |
1108 | ret |
1109 | ret |
1109 | 1110 | ||
1110 | .invalid: |
1111 | .invalid: |
1111 | mov dword[esp+32], -1 |
1112 | mov dword[esp+32], -1 |
1112 | mov dword[esp+20], EINVAL |
1113 | mov dword[esp+20], EINVAL |
1113 | ret |
1114 | ret |
1114 | 1115 | ||
1115 | 1116 | ||
1116 | 1117 | ||
1117 | ;----------------------------------------------------------------- |
1118 | ;----------------------------------------------------------------- |
1118 | ; |
1119 | ; |
1119 | ; SOCKET_set_options |
1120 | ; SOCKET_set_options |
1120 | ; |
1121 | ; |
1121 | ; IN: ecx = socket number |
1122 | ; IN: ecx = socket number |
1122 | ; edx = pointer to the options: |
1123 | ; edx = pointer to the options: |
1123 | ; dd level, optname, optlen, optval |
1124 | ; dd level, optname, optlen, optval |
1124 | ; OUT: -1 on error |
1125 | ; OUT: -1 on error |
1125 | ; |
1126 | ; |
1126 | ;----------------------------------------------------------------- |
1127 | ;----------------------------------------------------------------- |
1127 | align 4 |
1128 | align 4 |
1128 | SOCKET_set_opt: |
1129 | SOCKET_set_opt: |
1129 | 1130 | ||
1130 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n" |
1131 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n" |
1131 | 1132 | ||
1132 | call SOCKET_num_to_ptr |
1133 | call SOCKET_num_to_ptr |
1133 | jz .invalid |
1134 | jz .invalid |
1134 | 1135 | ||
1135 | cmp dword [edx], SOL_SOCKET |
1136 | cmp dword [edx], SOL_SOCKET |
1136 | jne .invalid |
1137 | jne .invalid |
1137 | 1138 | ||
1138 | cmp dword [edx+4], SO_BINDTODEVICE |
1139 | cmp dword [edx+4], SO_BINDTODEVICE |
1139 | je .bind |
1140 | je .bind |
1140 | 1141 | ||
1141 | .invalid: |
1142 | .invalid: |
1142 | mov dword[esp+32], -1 |
1143 | mov dword[esp+32], -1 |
1143 | mov dword[esp+20], EINVAL |
1144 | mov dword[esp+20], EINVAL |
1144 | ret |
1145 | ret |
1145 | 1146 | ||
1146 | .bind: |
1147 | .bind: |
1147 | cmp dword[edx+8], 0 |
1148 | cmp dword[edx+8], 0 |
1148 | je .unbind |
1149 | je .unbind |
1149 | 1150 | ||
1150 | movzx edx, byte[edx + 9] |
1151 | movzx edx, byte[edx + 9] |
1151 | cmp edx, NET_DEVICES_MAX |
1152 | cmp edx, NET_DEVICES_MAX |
1152 | ja .invalid |
1153 | ja .invalid |
1153 | 1154 | ||
1154 | mov edx, [NET_DRV_LIST + 4*edx] |
1155 | mov edx, [NET_DRV_LIST + 4*edx] |
1155 | test edx, edx |
1156 | test edx, edx |
1156 | jz .already |
1157 | jz .already |
1157 | mov [eax + SOCKET.device], edx |
1158 | mov [eax + SOCKET.device], edx |
1158 | 1159 | ||
1159 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx |
1160 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx |
1160 | 1161 | ||
1161 | mov dword[esp+32], 0 ; success! |
1162 | mov dword[esp+32], 0 ; success! |
1162 | ret |
1163 | ret |
1163 | 1164 | ||
1164 | .unbind: |
1165 | .unbind: |
1165 | mov [eax + SOCKET.device], 0 |
1166 | mov [eax + SOCKET.device], 0 |
1166 | 1167 | ||
1167 | mov dword[esp+32], 0 ; success! |
1168 | mov dword[esp+32], 0 ; success! |
1168 | ret |
1169 | ret |
1169 | 1170 | ||
1170 | .already: |
1171 | .already: |
1171 | mov dword[esp+20], EALREADY |
1172 | mov dword[esp+20], EALREADY |
1172 | mov dword[esp+32], -1 |
1173 | mov dword[esp+32], -1 |
1173 | ret |
1174 | ret |
1174 | 1175 | ||
1175 | 1176 | ||
1176 | 1177 | ||
1177 | 1178 | ||
1178 | ;----------------------------------------------------------------- |
1179 | ;----------------------------------------------------------------- |
1179 | ; |
1180 | ; |
1180 | ; SOCKET_pair |
1181 | ; SOCKET_pair |
1181 | ; |
1182 | ; |
1182 | ; Allocates a pair of linked LOCAL domain sockets |
1183 | ; Allocates a pair of linked LOCAL domain sockets |
1183 | ; |
1184 | ; |
1184 | ; IN: / |
1185 | ; IN: / |
1185 | ; OUT: eax is socket1 num, -1 on error |
1186 | ; OUT: eax is socket1 num, -1 on error |
1186 | ; ebx is socket2 num |
1187 | ; ebx is socket2 num |
1187 | ; |
1188 | ; |
1188 | ;----------------------------------------------------------------- |
1189 | ;----------------------------------------------------------------- |
1189 | align 4 |
1190 | align 4 |
1190 | SOCKET_pair: |
1191 | SOCKET_pair: |
1191 | 1192 | ||
1192 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n" |
1193 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n" |
1193 | 1194 | ||
1194 | call SOCKET_alloc |
1195 | call SOCKET_alloc |
- | 1196 | test eax, eax |
|
1195 | jz .nomem1 |
1197 | jz .nomem1 |
1196 | mov [esp+32], edi ; application's eax |
1198 | mov [esp+32], edi ; application's eax |
1197 | 1199 | ||
1198 | mov [eax + SOCKET.Domain], AF_LOCAL |
1200 | mov [eax + SOCKET.Domain], AF_LOCAL |
1199 | mov [eax + SOCKET.Type], SOCK_STREAM |
1201 | mov [eax + SOCKET.Type], SOCK_STREAM |
1200 | mov [eax + SOCKET.Protocol], 0 ;;; CHECKME |
1202 | mov [eax + SOCKET.Protocol], 0 ;;; CHECKME |
1201 | mov [eax + SOCKET.snd_proc], SOCKET_send_local |
1203 | mov [eax + SOCKET.snd_proc], SOCKET_send_local |
1202 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_local |
1204 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_local |
1203 | mov [eax + SOCKET.PID], 0 |
1205 | mov [eax + SOCKET.PID], 0 |
1204 | mov ebx, eax |
1206 | mov ebx, eax |
1205 | 1207 | ||
1206 | call SOCKET_alloc |
1208 | call SOCKET_alloc |
- | 1209 | test eax, eax |
|
1207 | jz .nomem2 |
1210 | jz .nomem2 |
1208 | mov [esp+20], edi ; application's ebx |
1211 | mov [esp+20], edi ; application's ebx |
1209 | 1212 | ||
1210 | mov [eax + SOCKET.Domain], AF_LOCAL |
1213 | mov [eax + SOCKET.Domain], AF_LOCAL |
1211 | mov [eax + SOCKET.Type], SOCK_STREAM |
1214 | mov [eax + SOCKET.Type], SOCK_STREAM |
1212 | mov [eax + SOCKET.Protocol], 0 ;;; CHECKME |
1215 | mov [eax + SOCKET.Protocol], 0 ;;; CHECKME |
1213 | mov [eax + SOCKET.snd_proc], SOCKET_send_local |
1216 | mov [eax + SOCKET.snd_proc], SOCKET_send_local |
1214 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_local |
1217 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_local |
1215 | mov [eax + SOCKET.PID], 0 |
1218 | mov [eax + SOCKET.PID], 0 |
1216 | 1219 | ||
1217 | ; Link the two sockets to eachother |
1220 | ; Link the two sockets to eachother |
1218 | mov [eax + SOCKET.device], ebx |
1221 | mov [eax + SOCKET.device], ebx |
1219 | mov [ebx + SOCKET.device], eax |
1222 | mov [ebx + SOCKET.device], eax |
1220 | 1223 | ||
1221 | lea eax, [eax + STREAM_SOCKET.rcv] |
1224 | lea eax, [eax + STREAM_SOCKET.rcv] |
1222 | call SOCKET_ring_create |
1225 | call SOCKET_ring_create |
- | 1226 | test eax, eax |
|
- | 1227 | jz .nomem1 |
|
1223 | 1228 | ||
1224 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1229 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1225 | call SOCKET_ring_create |
1230 | call SOCKET_ring_create |
1226 | pop eax |
1231 | test eax, eax |
- | 1232 | jz .nomem2 |
|
1227 | 1233 | ||
1228 | ret |
1234 | ret |
1229 | 1235 | ||
1230 | .nomem2: |
1236 | .nomem2: |
1231 | mov eax, ebx |
1237 | mov eax, ebx |
1232 | call SOCKET_free |
1238 | call SOCKET_free |
1233 | .nomem1: |
1239 | .nomem1: |
1234 | mov dword[esp+32], -1 |
1240 | mov dword[esp+32], -1 |
1235 | mov dword[esp+28], ENOMEM |
1241 | mov dword[esp+28], ENOMEM |
1236 | ret |
1242 | ret |
1237 | 1243 | ||
1238 | 1244 | ||
1239 | 1245 | ||
1240 | ;----------------------------------------------------------------- |
1246 | ;----------------------------------------------------------------- |
1241 | ; |
1247 | ; |
1242 | ; SOCKET_debug |
1248 | ; SOCKET_debug |
1243 | ; |
1249 | ; |
1244 | ; Copies socket variables to application buffer |
1250 | ; Copies socket variables to application buffer |
1245 | ; |
1251 | ; |
1246 | ; IN: ecx = socket number |
1252 | ; IN: ecx = socket number |
1247 | ; edx = pointer to buffer |
1253 | ; edx = pointer to buffer |
1248 | ; |
1254 | ; |
1249 | ; OUT: -1 on error |
1255 | ; OUT: -1 on error |
1250 | ;----------------------------------------------------------------- |
1256 | ;----------------------------------------------------------------- |
1251 | align 4 |
1257 | align 4 |
1252 | SOCKET_debug: |
1258 | SOCKET_debug: |
1253 | 1259 | ||
1254 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_debug\n" |
1260 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_debug\n" |
1255 | 1261 | ||
1256 | mov edi, edx |
1262 | mov edi, edx |
1257 | 1263 | ||
1258 | test ecx, ecx |
1264 | test ecx, ecx |
1259 | jz .returnall |
1265 | jz .returnall |
1260 | 1266 | ||
1261 | call SOCKET_num_to_ptr |
1267 | call SOCKET_num_to_ptr |
1262 | jz .invalid |
1268 | jz .invalid |
1263 | 1269 | ||
1264 | mov esi, eax |
1270 | mov esi, eax |
1265 | mov ecx, SOCKETBUFFSIZE/4 |
1271 | mov ecx, SOCKETBUFFSIZE/4 |
1266 | rep movsd |
1272 | rep movsd |
1267 | 1273 | ||
1268 | mov dword[esp+32], 0 |
1274 | mov dword[esp+32], 0 |
1269 | ret |
1275 | ret |
1270 | 1276 | ||
1271 | .returnall: |
1277 | .returnall: |
1272 | mov ebx, net_sockets |
1278 | mov ebx, net_sockets |
1273 | .next_socket: |
1279 | .next_socket: |
1274 | mov ebx, [ebx + SOCKET.NextPtr] |
1280 | mov ebx, [ebx + SOCKET.NextPtr] |
1275 | test ebx, ebx |
1281 | test ebx, ebx |
1276 | jz .done |
1282 | jz .done |
1277 | mov eax, [ebx + SOCKET.Number] |
1283 | mov eax, [ebx + SOCKET.Number] |
1278 | stosd |
1284 | stosd |
1279 | jmp .next_socket |
1285 | jmp .next_socket |
1280 | .done: |
1286 | .done: |
1281 | xor eax, eax |
1287 | xor eax, eax |
1282 | stosd |
1288 | stosd |
1283 | mov dword[esp+32], eax |
1289 | mov dword[esp+32], eax |
1284 | ret |
1290 | ret |
1285 | 1291 | ||
1286 | .invalid: |
1292 | .invalid: |
1287 | mov dword[esp+32], -1 |
1293 | mov dword[esp+32], -1 |
1288 | mov dword[esp+28], EINVAL |
1294 | mov dword[esp+28], EINVAL |
1289 | ret |
1295 | ret |
1290 | 1296 | ||
1291 | 1297 | ||
1292 | ;----------------------------------------------------------------- |
1298 | ;----------------------------------------------------------------- |
1293 | ; |
1299 | ; |
1294 | ; SOCKET_find_port |
1300 | ; SOCKET_find_port |
1295 | ; |
1301 | ; |
1296 | ; Fills in the local port number for TCP and UDP sockets |
1302 | ; Fills in the local port number for TCP and UDP sockets |
1297 | ; This procedure always works because the number of sockets is |
1303 | ; This procedure always works because the number of sockets is |
1298 | ; limited to a smaller number then the number of possible ports |
1304 | ; limited to a smaller number then the number of possible ports |
1299 | ; |
1305 | ; |
1300 | ; IN: eax = socket pointer |
1306 | ; IN: eax = socket pointer |
1301 | ; OUT: / |
1307 | ; OUT: / |
1302 | ; |
1308 | ; |
1303 | ;----------------------------------------------------------------- |
1309 | ;----------------------------------------------------------------- |
1304 | align 4 |
1310 | align 4 |
1305 | SOCKET_find_port: |
1311 | SOCKET_find_port: |
1306 | 1312 | ||
1307 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_find_port\n" |
1313 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_find_port\n" |
1308 | 1314 | ||
1309 | push ebx esi ecx |
1315 | push ebx esi ecx |
1310 | 1316 | ||
1311 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1317 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1312 | je .udp |
1318 | je .udp |
1313 | 1319 | ||
1314 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1320 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1315 | je .tcp |
1321 | je .tcp |
1316 | 1322 | ||
1317 | pop ecx esi ebx |
1323 | pop ecx esi ebx |
1318 | ret |
1324 | ret |
1319 | 1325 | ||
1320 | .udp: |
1326 | .udp: |
1321 | mov bx, [last_UDP_port] |
1327 | mov bx, [last_UDP_port] |
1322 | call .findit |
1328 | call .findit |
1323 | mov [last_UDP_port], bx |
1329 | mov [last_UDP_port], bx |
1324 | 1330 | ||
1325 | pop ecx esi ebx |
1331 | pop ecx esi ebx |
1326 | ret |
1332 | ret |
1327 | 1333 | ||
1328 | .tcp: |
1334 | .tcp: |
1329 | mov bx, [last_TCP_port] |
1335 | mov bx, [last_TCP_port] |
1330 | call .findit |
1336 | call .findit |
1331 | mov [last_TCP_port], bx |
1337 | mov [last_TCP_port], bx |
1332 | 1338 | ||
1333 | pop ecx esi ebx |
1339 | pop ecx esi ebx |
1334 | ret |
1340 | ret |
1335 | 1341 | ||
1336 | 1342 | ||
1337 | .restart: |
1343 | .restart: |
1338 | mov bx, MIN_EPHEMERAL_PORT_N |
1344 | mov bx, MIN_EPHEMERAL_PORT_N |
1339 | .findit: |
1345 | .findit: |
1340 | cmp bx, MAX_EPHEMERAL_PORT_N |
1346 | cmp bx, MAX_EPHEMERAL_PORT_N |
1341 | je .restart |
1347 | je .restart |
1342 | 1348 | ||
1343 | add bh, 1 |
1349 | add bh, 1 |
1344 | adc bl, 0 |
1350 | adc bl, 0 |
1345 | 1351 | ||
1346 | call SOCKET_check_port |
1352 | call SOCKET_check_port |
1347 | jz .findit |
1353 | jz .findit |
1348 | ret |
1354 | ret |
1349 | 1355 | ||
1350 | 1356 | ||
1351 | 1357 | ||
1352 | ;----------------------------------------------------------------- |
1358 | ;----------------------------------------------------------------- |
1353 | ; |
1359 | ; |
1354 | ; SOCKET_check_port (to be used with AF_INET only!) |
1360 | ; SOCKET_check_port (to be used with AF_INET only!) |
1355 | ; |
1361 | ; |
1356 | ; Checks if a local port number is unused |
1362 | ; Checks if a local port number is unused |
1357 | ; If the proposed port number is unused, it is filled in in the socket structure |
1363 | ; If the proposed port number is unused, it is filled in in the socket structure |
1358 | ; |
1364 | ; |
1359 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1365 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1360 | ; bx = proposed socket number (network byte order) |
1366 | ; bx = proposed socket number (network byte order) |
1361 | ; |
1367 | ; |
1362 | ; OUT: ZF = set on error |
1368 | ; OUT: ZF = set on error |
1363 | ; |
1369 | ; |
1364 | ;----------------------------------------------------------------- |
1370 | ;----------------------------------------------------------------- |
1365 | align 4 |
1371 | align 4 |
1366 | SOCKET_check_port: |
1372 | SOCKET_check_port: |
1367 | 1373 | ||
1368 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: " |
1374 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: " |
1369 | 1375 | ||
1370 | pusha |
1376 | pusha |
1371 | mov ecx, socket_mutex |
1377 | mov ecx, socket_mutex |
1372 | call mutex_lock |
1378 | call mutex_lock |
1373 | popa |
1379 | popa |
1374 | 1380 | ||
1375 | mov ecx, [eax + SOCKET.Protocol] |
1381 | mov ecx, [eax + SOCKET.Protocol] |
1376 | mov edx, [eax + IP_SOCKET.LocalIP] |
1382 | mov edx, [eax + IP_SOCKET.LocalIP] |
1377 | mov esi, net_sockets |
1383 | mov esi, net_sockets |
1378 | 1384 | ||
1379 | .next_socket: |
1385 | .next_socket: |
1380 | mov esi, [esi + SOCKET.NextPtr] |
1386 | mov esi, [esi + SOCKET.NextPtr] |
1381 | or esi, esi |
1387 | or esi, esi |
1382 | jz .port_ok |
1388 | jz .port_ok |
1383 | 1389 | ||
1384 | cmp [esi + SOCKET.Protocol], ecx |
1390 | cmp [esi + SOCKET.Protocol], ecx |
1385 | jne .next_socket |
1391 | jne .next_socket |
1386 | 1392 | ||
1387 | cmp [esi + IP_SOCKET.LocalIP], edx |
1393 | cmp [esi + IP_SOCKET.LocalIP], edx |
1388 | jne .next_socket |
1394 | jne .next_socket |
1389 | 1395 | ||
1390 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1396 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1391 | jne .next_socket |
1397 | jne .next_socket |
1392 | 1398 | ||
1393 | pusha |
1399 | pusha |
1394 | mov ecx, socket_mutex |
1400 | mov ecx, socket_mutex |
1395 | call mutex_unlock |
1401 | call mutex_unlock |
1396 | popa |
1402 | popa |
1397 | 1403 | ||
1398 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf |
1404 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf |
1399 | ret |
1405 | ret |
1400 | 1406 | ||
1401 | .port_ok: |
1407 | .port_ok: |
1402 | pusha |
1408 | pusha |
1403 | mov ecx, socket_mutex |
1409 | mov ecx, socket_mutex |
1404 | call mutex_unlock |
1410 | call mutex_unlock |
1405 | popa |
1411 | popa |
1406 | 1412 | ||
1407 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf |
1413 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf |
1408 | mov [eax + UDP_SOCKET.LocalPort], bx |
1414 | mov [eax + UDP_SOCKET.LocalPort], bx |
1409 | or bx, bx ; clear the zero-flag |
1415 | or bx, bx ; clear the zero-flag |
1410 | ret |
1416 | ret |
1411 | 1417 | ||
1412 | 1418 | ||
1413 | 1419 | ||
1414 | ;----------------------------------------------------------------- |
1420 | ;----------------------------------------------------------------- |
1415 | ; |
1421 | ; |
1416 | ; SOCKET_input |
1422 | ; SOCKET_input |
1417 | ; |
1423 | ; |
1418 | ; Updates a (stateless) socket with received data |
1424 | ; Updates a (stateless) socket with received data |
1419 | ; |
1425 | ; |
1420 | ; Note: the mutex should already be set ! |
1426 | ; Note: the mutex should already be set ! |
1421 | ; |
1427 | ; |
1422 | ; IN: eax = socket ptr |
1428 | ; IN: eax = socket ptr |
1423 | ; ecx = data size |
1429 | ; ecx = data size |
1424 | ; esi = ptr to data |
1430 | ; esi = ptr to data |
1425 | ; [esp] = ptr to buf |
1431 | ; [esp] = ptr to buf |
1426 | ; [esp + 4] = buf size |
1432 | ; [esp + 4] = buf size |
1427 | ; |
1433 | ; |
1428 | ; OUT: / |
1434 | ; OUT: / |
1429 | ; |
1435 | ; |
1430 | ;----------------------------------------------------------------- |
1436 | ;----------------------------------------------------------------- |
1431 | align 4 |
1437 | align 4 |
1432 | SOCKET_input: |
1438 | SOCKET_input: |
1433 | 1439 | ||
1434 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1440 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1435 | 1441 | ||
1436 | mov [esp+4], ecx |
1442 | mov [esp+4], ecx |
1437 | push esi |
1443 | push esi |
1438 | mov esi, esp |
1444 | mov esi, esp |
1439 | 1445 | ||
1440 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1446 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1441 | 1447 | ||
1442 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: success\n" |
1448 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: success\n" |
1443 | add esp, sizeof.socket_queue_entry |
1449 | add esp, sizeof.socket_queue_entry |
1444 | 1450 | ||
1445 | pusha |
1451 | pusha |
1446 | lea ecx, [eax + SOCKET.mutex] |
1452 | lea ecx, [eax + SOCKET.mutex] |
1447 | call mutex_unlock |
1453 | call mutex_unlock |
1448 | popa |
1454 | popa |
1449 | 1455 | ||
1450 | jmp SOCKET_notify |
1456 | jmp SOCKET_notify |
1451 | 1457 | ||
1452 | .full: |
1458 | .full: |
1453 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket %x is full!\n", eax |
1459 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket %x is full!\n", eax |
1454 | 1460 | ||
1455 | pusha |
1461 | pusha |
1456 | lea ecx, [eax + SOCKET.mutex] |
1462 | lea ecx, [eax + SOCKET.mutex] |
1457 | call mutex_unlock |
1463 | call mutex_unlock |
1458 | popa |
1464 | popa |
1459 | 1465 | ||
1460 | call NET_packet_free |
1466 | call NET_packet_free |
1461 | add esp, 8 |
1467 | add esp, 8 |
1462 | 1468 | ||
1463 | ret |
1469 | ret |
1464 | 1470 | ||
1465 | 1471 | ||
1466 | ;-------------------------- |
1472 | ;-------------------------- |
1467 | ; |
1473 | ; |
1468 | ; eax = ptr to ring struct (just a buffer of the right size) |
1474 | ; IN: eax = ptr to ring struct (just a buffer of the right size) |
- | 1475 | ; OUT: eax = unchanged / 0 on error |
|
1469 | ; |
1476 | ; |
1470 | align 4 |
1477 | align 4 |
1471 | SOCKET_ring_create: |
1478 | SOCKET_ring_create: |
1472 | 1479 | ||
1473 | push esi |
1480 | push esi |
1474 | mov esi, eax |
1481 | mov esi, eax |
1475 | 1482 | ||
1476 | push edx |
1483 | push edx |
1477 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1484 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1478 | pop edx |
1485 | pop edx |
- | 1486 | test eax, eax |
|
- | 1487 | jz .fail |
|
1479 | 1488 | ||
1480 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax |
1489 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax |
1481 | 1490 | ||
1482 | pusha |
1491 | pusha |
1483 | lea ecx, [esi + RING_BUFFER.mutex] |
1492 | lea ecx, [esi + RING_BUFFER.mutex] |
1484 | call mutex_init |
1493 | call mutex_init |
1485 | popa |
1494 | popa |
1486 | 1495 | ||
1487 | mov [esi + RING_BUFFER.start_ptr], eax |
1496 | mov [esi + RING_BUFFER.start_ptr], eax |
1488 | mov [esi + RING_BUFFER.write_ptr], eax |
1497 | mov [esi + RING_BUFFER.write_ptr], eax |
1489 | mov [esi + RING_BUFFER.read_ptr], eax |
1498 | mov [esi + RING_BUFFER.read_ptr], eax |
1490 | mov [esi + RING_BUFFER.size], 0 |
1499 | mov [esi + RING_BUFFER.size], 0 |
1491 | add eax, SOCKET_MAXDATA |
1500 | add eax, SOCKET_MAXDATA |
1492 | mov [esi + RING_BUFFER.end_ptr], eax |
1501 | mov [esi + RING_BUFFER.end_ptr], eax |
1493 | mov eax, esi |
1502 | mov eax, esi |
1494 | pop esi |
1503 | pop esi |
- | 1504 | ||
1495 | 1505 | .fail: |
|
1496 | ret |
1506 | ret |
1497 | 1507 | ||
1498 | ;----------------------------------------------------------------- |
1508 | ;----------------------------------------------------------------- |
1499 | ; |
1509 | ; |
1500 | ; SOCKET_ring_write |
1510 | ; SOCKET_ring_write |
1501 | ; |
1511 | ; |
1502 | ; Adds data to a stream socket, and updates write pointer and size |
1512 | ; Adds data to a stream socket, and updates write pointer and size |
1503 | ; |
1513 | ; |
1504 | ; IN: eax = ptr to ring struct |
1514 | ; IN: eax = ptr to ring struct |
1505 | ; ecx = data size |
1515 | ; ecx = data size |
1506 | ; esi = ptr to data |
1516 | ; esi = ptr to data |
1507 | ; |
1517 | ; |
1508 | ; OUT: ecx = number of bytes stored |
1518 | ; OUT: ecx = number of bytes stored |
1509 | ; |
1519 | ; |
1510 | ;----------------------------------------------------------------- |
1520 | ;----------------------------------------------------------------- |
1511 | align 4 |
1521 | align 4 |
1512 | SOCKET_ring_write: |
1522 | SOCKET_ring_write: |
1513 | 1523 | ||
1514 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1524 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1515 | 1525 | ||
1516 | ; lock mutex |
1526 | ; lock mutex |
1517 | pusha |
1527 | pusha |
1518 | lea ecx, [eax + RING_BUFFER.mutex] |
1528 | lea ecx, [eax + RING_BUFFER.mutex] |
1519 | call mutex_lock ; TODO: check what registers this function actually destroys |
1529 | call mutex_lock ; TODO: check what registers this function actually destroys |
1520 | popa |
1530 | popa |
1521 | 1531 | ||
1522 | ; calculate available size |
1532 | ; calculate available size |
1523 | mov edi, SOCKET_MAXDATA |
1533 | mov edi, SOCKET_MAXDATA |
1524 | sub edi, [eax + RING_BUFFER.size] ; available buffer size in edi |
1534 | sub edi, [eax + RING_BUFFER.size] ; available buffer size in edi |
1525 | cmp ecx, edi |
1535 | cmp ecx, edi |
1526 | jbe .copy |
1536 | jbe .copy |
1527 | mov ecx, edi |
1537 | mov ecx, edi |
1528 | .copy: |
1538 | .copy: |
1529 | mov edi, [eax + RING_BUFFER.write_ptr] |
1539 | mov edi, [eax + RING_BUFFER.write_ptr] |
1530 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
1540 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
1531 | 1541 | ||
1532 | ; update write ptr |
1542 | ; update write ptr |
1533 | push edi |
1543 | push edi |
1534 | add edi, ecx |
1544 | add edi, ecx |
1535 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1545 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1536 | jb @f |
1546 | jb @f |
1537 | sub edi, SOCKET_MAXDATA ; WRAP |
1547 | sub edi, SOCKET_MAXDATA ; WRAP |
1538 | @@: |
1548 | @@: |
- | 1549 | ||
1539 | mov [eax + RING_BUFFER.write_ptr], edi |
1550 | mov [eax + RING_BUFFER.write_ptr], edi |
1540 | pop edi |
1551 | pop edi |
1541 | 1552 | ||
1542 | ; update size |
1553 | ; update size |
1543 | add [eax + RING_BUFFER.size], ecx |
1554 | add [eax + RING_BUFFER.size], ecx |
1544 | 1555 | ||
1545 | ; copy the data |
1556 | ; copy the data |
1546 | push ecx |
1557 | push ecx |
1547 | shr ecx, 1 |
1558 | shr ecx, 1 |
1548 | jnc .nb |
1559 | jnc .nb |
1549 | movsb |
1560 | movsb |
1550 | .nb: |
1561 | .nb: |
1551 | shr ecx, 1 |
1562 | shr ecx, 1 |
1552 | jnc .nw |
1563 | jnc .nw |
1553 | movsw |
1564 | movsw |
1554 | .nw: |
1565 | .nw: |
1555 | test ecx, ecx |
1566 | test ecx, ecx |
1556 | jz .nd |
1567 | jz .nd |
1557 | rep movsd |
1568 | rep movsd |
1558 | .nd: |
1569 | .nd: |
1559 | pop ecx |
1570 | pop ecx |
1560 | 1571 | ||
1561 | ; unlock mutex |
1572 | ; unlock mutex |
1562 | pusha |
1573 | pusha |
1563 | lea ecx, [eax + RING_BUFFER.mutex] |
1574 | lea ecx, [eax + RING_BUFFER.mutex] |
1564 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1575 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1565 | popa |
1576 | popa |
1566 | 1577 | ||
1567 | ret |
1578 | ret |
1568 | 1579 | ||
1569 | ;----------------------------------------------------------------- |
1580 | ;----------------------------------------------------------------- |
1570 | ; |
1581 | ; |
1571 | ; SOCKET_ring_read |
1582 | ; SOCKET_ring_read |
1572 | ; |
1583 | ; |
1573 | ; IN: eax = ring struct ptr |
1584 | ; IN: eax = ring struct ptr |
1574 | ; ecx = bytes to read |
1585 | ; ecx = bytes to read |
1575 | ; edx = offset |
1586 | ; edx = offset |
1576 | ; edi = ptr to buffer start |
1587 | ; edi = ptr to buffer start |
1577 | ; |
1588 | ; |
1578 | ; OUT: eax = unchanged |
1589 | ; OUT: eax = unchanged |
1579 | ; ecx = number of bytes read (0 on error) |
1590 | ; ecx = number of bytes read (0 on error) |
1580 | ; edx = destroyed |
1591 | ; edx = destroyed |
1581 | ; esi = destroyed |
1592 | ; esi = destroyed |
1582 | ; edi = ptr to buffer end |
1593 | ; edi = ptr to buffer end |
1583 | ; |
1594 | ; |
1584 | ;----------------------------------------------------------------- |
1595 | ;----------------------------------------------------------------- |
1585 | align 4 |
1596 | align 4 |
1586 | SOCKET_ring_read: |
1597 | SOCKET_ring_read: |
1587 | 1598 | ||
1588 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1599 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1589 | 1600 | ||
1590 | pusha |
1601 | pusha |
1591 | lea ecx, [eax + RING_BUFFER.mutex] |
1602 | lea ecx, [eax + RING_BUFFER.mutex] |
1592 | call mutex_lock ; TODO: check what registers this function actually destroys |
1603 | call mutex_lock ; TODO: check what registers this function actually destroys |
1593 | popa |
1604 | popa |
1594 | 1605 | ||
1595 | mov esi, [eax + RING_BUFFER.read_ptr] |
1606 | mov esi, [eax + RING_BUFFER.read_ptr] |
1596 | add esi, edx ; esi = start_ptr + offset |
1607 | add esi, edx ; esi = start_ptr + offset |
1597 | 1608 | ||
1598 | neg edx |
1609 | neg edx |
1599 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1610 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1600 | jle .no_data_at_all |
1611 | jle .no_data_at_all |
1601 | 1612 | ||
1602 | pusha |
1613 | pusha |
1603 | lea ecx, [eax + RING_BUFFER.mutex] |
1614 | lea ecx, [eax + RING_BUFFER.mutex] |
1604 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1615 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1605 | popa |
1616 | popa |
1606 | 1617 | ||
1607 | cmp ecx, edx |
1618 | cmp ecx, edx |
1608 | ja .less_data |
1619 | ja .less_data |
1609 | 1620 | ||
1610 | .copy: |
1621 | .copy: |
1611 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1622 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1612 | push ecx |
1623 | push ecx |
1613 | shr ecx, 1 |
1624 | shr ecx, 1 |
1614 | jnc .nb |
1625 | jnc .nb |
1615 | movsb |
1626 | movsb |
1616 | .nb: |
1627 | .nb: |
1617 | shr ecx, 1 |
1628 | shr ecx, 1 |
1618 | jnc .nw |
1629 | jnc .nw |
1619 | movsw |
1630 | movsw |
1620 | .nw: |
1631 | .nw: |
1621 | test ecx, ecx |
1632 | test ecx, ecx |
1622 | jz .nd |
1633 | jz .nd |
1623 | rep movsd |
1634 | rep movsd |
1624 | .nd: |
1635 | .nd: |
1625 | pop ecx |
1636 | pop ecx |
1626 | ret |
1637 | ret |
1627 | 1638 | ||
1628 | .no_data_at_all: |
1639 | .no_data_at_all: |
1629 | pusha |
1640 | pusha |
1630 | lea ecx, [eax + RING_BUFFER.mutex] |
1641 | lea ecx, [eax + RING_BUFFER.mutex] |
1631 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1642 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1632 | popa |
1643 | popa |
1633 | 1644 | ||
1634 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: no data at all!\n" |
1645 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: no data at all!\n" |
1635 | xor ecx, ecx |
1646 | xor ecx, ecx |
1636 | ret |
1647 | ret |
1637 | 1648 | ||
1638 | .less_data: |
1649 | .less_data: |
1639 | mov ecx, edx |
1650 | mov ecx, edx |
1640 | jmp .copy |
1651 | jmp .copy |
1641 | 1652 | ||
1642 | 1653 | ||
1643 | ;----------------------------------------------------------------- |
1654 | ;----------------------------------------------------------------- |
1644 | ; |
1655 | ; |
1645 | ; SOCKET_ring_free |
1656 | ; SOCKET_ring_free |
1646 | ; |
1657 | ; |
1647 | ; Free's some bytes from the ringbuffer |
1658 | ; Free's some bytes from the ringbuffer |
1648 | ; |
1659 | ; |
1649 | ; IN: eax = ptr to ring struct |
1660 | ; IN: eax = ptr to ring struct |
1650 | ; ecx = data size |
1661 | ; ecx = data size |
1651 | ; |
1662 | ; |
1652 | ; OUT: ecx = number of bytes free-ed |
1663 | ; OUT: ecx = number of bytes free-ed |
1653 | ; |
1664 | ; |
1654 | ;----------------------------------------------------------------- |
1665 | ;----------------------------------------------------------------- |
1655 | align 4 |
1666 | align 4 |
1656 | SOCKET_ring_free: |
1667 | SOCKET_ring_free: |
1657 | 1668 | ||
1658 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1669 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1659 | 1670 | ||
1660 | push eax ecx |
1671 | push eax ecx |
1661 | lea ecx, [eax + RING_BUFFER.mutex] |
1672 | lea ecx, [eax + RING_BUFFER.mutex] |
1662 | call mutex_lock ; TODO: check what registers this function actually destroys |
1673 | call mutex_lock ; TODO: check what registers this function actually destroys |
1663 | pop ecx eax |
1674 | pop ecx eax |
1664 | 1675 | ||
1665 | sub [eax + RING_BUFFER.size], ecx |
1676 | sub [eax + RING_BUFFER.size], ecx |
1666 | jb .error |
1677 | jb .error |
1667 | add [eax + RING_BUFFER.read_ptr], ecx |
1678 | add [eax + RING_BUFFER.read_ptr], ecx |
1668 | 1679 | ||
1669 | mov edx, [eax + RING_BUFFER.end_ptr] |
1680 | mov edx, [eax + RING_BUFFER.end_ptr] |
1670 | cmp [eax + RING_BUFFER.read_ptr], edx |
1681 | cmp [eax + RING_BUFFER.read_ptr], edx |
1671 | jb @f |
1682 | jb @f |
1672 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1683 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1673 | @@: |
1684 | @@: |
1674 | 1685 | ||
1675 | push eax ecx |
1686 | push eax ecx |
1676 | lea ecx, [eax + RING_BUFFER.mutex] ; TODO: check what registers this function actually destroys |
1687 | lea ecx, [eax + RING_BUFFER.mutex] ; TODO: check what registers this function actually destroys |
1677 | call mutex_unlock |
1688 | call mutex_unlock |
1678 | pop ecx eax |
1689 | pop ecx eax |
1679 | 1690 | ||
1680 | ret |
1691 | ret |
1681 | 1692 | ||
1682 | .error: ; we could free all available bytes, but that would be stupid, i guess.. |
1693 | .error: ; we could free all available bytes, but that would be stupid, i guess.. |
1683 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: buffer=%x error!\n", eax |
1694 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: buffer=%x error!\n", eax |
1684 | add [eax + RING_BUFFER.size], ecx |
1695 | add [eax + RING_BUFFER.size], ecx |
1685 | 1696 | ||
1686 | push eax |
1697 | push eax |
1687 | lea ecx, [eax + RING_BUFFER.mutex] |
1698 | lea ecx, [eax + RING_BUFFER.mutex] |
1688 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1699 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1689 | pop eax |
1700 | pop eax |
1690 | 1701 | ||
1691 | xor ecx, ecx |
1702 | xor ecx, ecx |
1692 | ret |
1703 | ret |
1693 | 1704 | ||
1694 | 1705 | ||
1695 | ;----------------------------------------------------------------- |
1706 | ;----------------------------------------------------------------- |
1696 | ; |
1707 | ; |
1697 | ; SOCKET_block |
1708 | ; SOCKET_block |
1698 | ; |
1709 | ; |
1699 | ; Suspends the thread attached to a socket |
1710 | ; Suspends the thread attached to a socket |
1700 | ; |
1711 | ; |
1701 | ; IN: eax = socket ptr |
1712 | ; IN: eax = socket ptr |
1702 | ; OUT: eax = unchanged |
1713 | ; OUT: eax = unchanged |
1703 | ; |
1714 | ; |
1704 | ;----------------------------------------------------------------- |
1715 | ;----------------------------------------------------------------- |
1705 | align 4 |
1716 | align 4 |
1706 | SOCKET_block: |
1717 | SOCKET_block: |
1707 | 1718 | ||
1708 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax |
1719 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax |
1709 | - | ||
1710 | pushf |
1720 | |
- | 1721 | push eax |
|
- | 1722 | ||
1711 | push eax |
1723 | pushf |
1712 | cli |
1724 | cli |
1713 | 1725 | ||
1714 | ; Set the 'socket is blocked' flag |
1726 | ; Set the 'socket is blocked' flag |
1715 | or [eax + SOCKET.state], SS_BLOCKED |
1727 | or [eax + SOCKET.state], SS_BLOCKED |
1716 | 1728 | ||
1717 | ; Suspend the thread |
1729 | ; Suspend the thread |
1718 | push edx |
1730 | push edx |
1719 | mov edx, [TASK_BASE] |
1731 | mov edx, [TASK_BASE] |
1720 | mov [edx + TASKDATA.state], 1 ; Suspended |
1732 | mov [edx + TASKDATA.state], 1 ; Suspended |
1721 | 1733 | ||
1722 | ; Remember the thread ID so we can wake it up again |
1734 | ; Remember the thread ID so we can wake it up again |
1723 | mov edx, [edx + TASKDATA.pid] |
1735 | mov edx, [edx + TASKDATA.pid] |
1724 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx |
1736 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx |
1725 | mov [eax + SOCKET.TID], edx |
1737 | mov [eax + SOCKET.TID], edx |
1726 | pop edx |
1738 | pop edx |
- | 1739 | popf |
|
1727 | 1740 | ||
1728 | call change_task |
1741 | call change_task |
1729 | pop eax |
1742 | pop eax |
1730 | popf |
- | |
1731 | 1743 | ||
1732 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n" |
1744 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n" |
1733 | 1745 | ||
1734 | ret |
1746 | ret |
1735 | 1747 | ||
1736 | 1748 | ||
1737 | ;----------------------------------------------------------------- |
1749 | ;----------------------------------------------------------------- |
1738 | ; |
1750 | ; |
1739 | ; SOCKET_notify |
1751 | ; SOCKET_notify |
1740 | ; |
1752 | ; |
1741 | ; notify's the owner of a socket that something happened |
1753 | ; notify's the owner of a socket that something happened |
1742 | ; |
1754 | ; |
1743 | ; IN: eax = socket ptr |
1755 | ; IN: eax = socket ptr |
1744 | ; OUT: eax = unchanged |
1756 | ; OUT: eax = unchanged |
1745 | ; |
1757 | ; |
1746 | ;----------------------------------------------------------------- |
1758 | ;----------------------------------------------------------------- |
1747 | align 4 |
1759 | align 4 |
1748 | SOCKET_notify: |
1760 | SOCKET_notify: |
1749 | 1761 | ||
1750 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: %x\n", eax |
1762 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: %x\n", eax |
1751 | 1763 | ||
1752 | call SOCKET_check |
1764 | call SOCKET_check |
1753 | jz .error |
1765 | jz .error |
1754 | - | ||
1755 | test [eax + SOCKET.state], SS_BLOCKED |
- | |
1756 | jnz .unblock |
- | |
1757 | - | ||
1758 | ; test [eax + SOCKET.options], SO_NONBLOCK |
- | |
1759 | ; jz .error |
- | |
1760 | - | ||
1761 | push eax ecx esi |
- | |
1762 | - | ||
1763 | ; socket exists and is of non blocking type. |
- | |
1764 | ; We'll try to flag an event to the thread |
- | |
1765 | - | ||
1766 | mov eax, [eax + SOCKET.TID] |
- | |
1767 | test eax, eax |
- | |
1768 | jz .done |
- | |
1769 | mov ecx, 1 |
1766 | |
1770 | mov esi, TASK_DATA + TASKDATA.pid |
- | |
1771 | - | ||
1772 | .next_pid: |
- | |
1773 | cmp [esi], eax |
- | |
1774 | je .found_pid |
- | |
1775 | inc ecx |
- | |
1776 | add esi, 0x20 |
- | |
1777 | cmp ecx, [TASK_COUNT] |
- | |
1778 | jbe .next_pid |
- | |
1779 | ; PID not found, TODO: close socket! |
- | |
1780 | jmp .done |
- | |
1781 | - | ||
1782 | .found_pid: |
- | |
1783 | shl ecx, 8 |
- | |
1784 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
- | |
1785 | - | ||
1786 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax |
- | |
1787 | jmp .done |
- | |
1788 | - | ||
1789 | .unblock: |
1767 | ; Find the associated thread's TASK_DATA |
1790 | push eax ecx esi |
- | |
1791 | ; Clear the 'socket is blocked' flag |
- | |
1792 | and [eax + SOCKET.state], not SS_BLOCKED |
- | |
1793 | - | ||
1794 | ; Find the thread's TASK_DATA |
1768 | push ebx ecx esi |
1795 | mov eax, [eax + SOCKET.TID] |
1769 | mov ebx, [eax + SOCKET.TID] |
1796 | test eax, eax |
1770 | test ebx, ebx |
1797 | jz .error |
1771 | jz .error2 |
1798 | xor ecx, ecx |
1772 | xor ecx, ecx |
1799 | inc ecx |
1773 | inc ecx |
1800 | mov esi, TASK_DATA |
1774 | mov esi, TASK_DATA |
1801 | .next: |
1775 | .next: |
1802 | cmp [esi + TASKDATA.pid], eax |
1776 | cmp [esi + TASKDATA.pid], ebx |
1803 | je .found |
1777 | je .found |
1804 | inc ecx |
1778 | inc ecx |
1805 | add esi, 0x20 |
1779 | add esi, 0x20 |
1806 | cmp ecx, [TASK_COUNT] |
1780 | cmp ecx, [TASK_COUNT] |
1807 | jbe .next |
1781 | jbe .next |
- | 1782 | ||
- | 1783 | .error2: |
|
- | 1784 | ; PID not found, TODO: close socket! |
|
- | 1785 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx |
|
1808 | jmp .error |
1786 | pop esi ecx ebx |
- | 1787 | ret |
|
- | 1788 | ||
- | 1789 | .error: |
|
- | 1790 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: invalid socket ptr: 0x%x !\n", eax |
|
- | 1791 | ret |
|
- | 1792 | ||
1809 | .found: |
1793 | .found: |
- | 1794 | test [eax + SOCKET.state], SS_BLOCKED |
|
- | 1795 | jnz .un_block |
|
- | 1796 | ||
1810 | 1797 | ; socket and thread exists and socket is of non blocking type. |
|
1811 | ; Run the thread |
1798 | ; We'll try to flag an event to the thread. |
1812 | mov [esi + TASKDATA.state], 0 ; Running |
1799 | shl ecx, 8 |
1813 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" |
- | |
- | 1800 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
|
1814 | 1801 | ||
- | 1802 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax |
|
- | 1803 | pop esi ecx ebx |
|
1815 | .done: |
1804 | ret |
- | 1805 | ||
- | 1806 | ||
- | 1807 | .un_block: |
|
- | 1808 | ; socket and thread exists and socket is of blocking type |
|
- | 1809 | ; We'll try to unblock it. |
|
- | 1810 | and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag |
|
- | 1811 | mov [esi + TASKDATA.state], 0 ; Run the thread |
|
1816 | pop esi ecx eax |
1812 | |
1817 | 1813 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" |
|
1818 | .error: |
1814 | pop esi ecx ebx |
1819 | ret |
1815 | ret |
1820 | 1816 | ||
1821 | 1817 | ||
1822 | ;-------------------------------------------------------------------- |
1818 | ;-------------------------------------------------------------------- |
1823 | ; |
1819 | ; |
1824 | ; SOCKET_alloc |
1820 | ; SOCKET_alloc |
1825 | ; |
1821 | ; |
1826 | ; Allocate memory for socket data and put new socket into the list |
1822 | ; Allocate memory for socket data and put new socket into the list |
1827 | ; Newly created socket is initialized with calling PID and number and |
1823 | ; Newly created socket is initialized with calling PID and number and |
1828 | ; put into beginning of list (which is a fastest way). |
1824 | ; put into beginning of list (which is a fastest way). |
1829 | ; |
1825 | ; |
1830 | ; IN: / |
1826 | ; IN: / |
1831 | ; OUT: eax = 0 on error, socket ptr otherwise |
1827 | ; OUT: eax = 0 on error, socket ptr otherwise |
1832 | ; edi = socket number |
1828 | ; edi = socket number |
1833 | ; ZF = cleared on error |
- | |
1834 | ; |
1829 | ; |
1835 | ;-------------------------------------------------------------------- |
1830 | ;-------------------------------------------------------------------- |
1836 | align 4 |
1831 | align 4 |
1837 | SOCKET_alloc: |
1832 | SOCKET_alloc: |
1838 | 1833 | ||
1839 | push ebx |
1834 | push ebx |
1840 | 1835 | ||
1841 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1836 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1842 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax |
1837 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax |
1843 | or eax, eax |
1838 | or eax, eax |
1844 | jz .exit |
1839 | jz .exit |
1845 | 1840 | ||
1846 | ; zero-initialize allocated memory |
1841 | ; zero-initialize allocated memory |
1847 | push eax |
1842 | push eax |
1848 | mov edi, eax |
1843 | mov edi, eax |
1849 | mov ecx, SOCKETBUFFSIZE / 4 |
1844 | mov ecx, SOCKETBUFFSIZE / 4 |
1850 | xor eax, eax |
1845 | xor eax, eax |
1851 | rep stosd |
1846 | rep stosd |
1852 | pop eax |
1847 | pop eax |
1853 | 1848 | ||
1854 | ; set send-and receive procedures to return -1 |
1849 | ; set send-and receive procedures to return -1 |
1855 | mov [eax + SOCKET.snd_proc], .not_yet |
1850 | mov [eax + SOCKET.snd_proc], .not_yet |
1856 | mov [eax + SOCKET.rcv_proc], .not_yet |
1851 | mov [eax + SOCKET.rcv_proc], .not_yet |
1857 | 1852 | ||
1858 | pusha |
1853 | pusha |
1859 | mov ecx, socket_mutex |
1854 | mov ecx, socket_mutex |
1860 | call mutex_lock |
1855 | call mutex_lock |
1861 | popa |
1856 | popa |
1862 | 1857 | ||
1863 | ; find first free socket number and use it |
1858 | ; find first free socket number and use it |
1864 | mov edi, [last_socket_num] |
1859 | mov edi, [last_socket_num] |
1865 | .next_socket_number: |
1860 | .next_socket_number: |
1866 | inc edi |
1861 | inc edi |
1867 | jz .next_socket_number ; avoid socket nr 0 |
1862 | jz .next_socket_number ; avoid socket nr 0 |
1868 | cmp edi, -1 |
1863 | cmp edi, -1 |
1869 | je .next_socket_number ; avoid socket nr -1 |
1864 | je .next_socket_number ; avoid socket nr -1 |
1870 | mov ebx, net_sockets |
1865 | mov ebx, net_sockets |
1871 | .next_socket: |
1866 | .next_socket: |
1872 | mov ebx, [ebx + SOCKET.NextPtr] |
1867 | mov ebx, [ebx + SOCKET.NextPtr] |
1873 | test ebx, ebx |
1868 | test ebx, ebx |
1874 | jz .last_socket |
1869 | jz .last_socket |
1875 | 1870 | ||
1876 | cmp [ebx + SOCKET.Number], edi |
1871 | cmp [ebx + SOCKET.Number], edi |
1877 | jne .next_socket |
1872 | jne .next_socket |
1878 | jmp .next_socket_number |
1873 | jmp .next_socket_number |
1879 | 1874 | ||
1880 | .last_socket: |
1875 | .last_socket: |
1881 | mov [last_socket_num], edi |
1876 | mov [last_socket_num], edi |
1882 | mov [eax + SOCKET.Number], edi |
1877 | mov [eax + SOCKET.Number], edi |
1883 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: number=%u\n", edi |
1878 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: number=%u\n", edi |
1884 | 1879 | ||
1885 | ; Fill in PID |
1880 | ; Fill in PID |
1886 | mov ebx, [TASK_BASE] |
1881 | mov ebx, [TASK_BASE] |
1887 | mov ebx, [ebx + TASKDATA.pid] |
1882 | mov ebx, [ebx + TASKDATA.pid] |
1888 | mov [eax + SOCKET.PID], ebx |
1883 | mov [eax + SOCKET.PID], ebx |
1889 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1884 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1890 | 1885 | ||
1891 | ; init mutex |
1886 | ; init mutex |
1892 | pusha |
1887 | pusha |
1893 | lea ecx, [eax + SOCKET.mutex] |
1888 | lea ecx, [eax + SOCKET.mutex] |
1894 | call mutex_init |
1889 | call mutex_init |
1895 | popa |
1890 | popa |
1896 | 1891 | ||
1897 | ; add socket to the list by re-arranging some pointers |
1892 | ; add socket to the list by re-arranging some pointers |
1898 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1893 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1899 | 1894 | ||
1900 | mov [eax + SOCKET.PrevPtr], net_sockets |
1895 | mov [eax + SOCKET.PrevPtr], net_sockets |
1901 | mov [eax + SOCKET.NextPtr], ebx |
1896 | mov [eax + SOCKET.NextPtr], ebx |
1902 | 1897 | ||
1903 | test ebx, ebx |
1898 | test ebx, ebx |
1904 | jz @f |
1899 | jz @f |
1905 | 1900 | ||
1906 | pusha |
1901 | pusha |
1907 | lea ecx, [ebx + SOCKET.mutex] |
1902 | lea ecx, [ebx + SOCKET.mutex] |
1908 | call mutex_lock |
1903 | call mutex_lock |
1909 | popa |
1904 | popa |
1910 | 1905 | ||
1911 | mov [ebx + SOCKET.PrevPtr], eax |
1906 | mov [ebx + SOCKET.PrevPtr], eax |
1912 | 1907 | ||
1913 | pusha |
1908 | pusha |
1914 | lea ecx, [ebx + SOCKET.mutex] |
1909 | lea ecx, [ebx + SOCKET.mutex] |
1915 | call mutex_unlock |
1910 | call mutex_unlock |
1916 | popa |
1911 | popa |
1917 | @@: |
1912 | @@: |
1918 | 1913 | ||
1919 | mov [net_sockets + SOCKET.NextPtr], eax |
1914 | mov [net_sockets + SOCKET.NextPtr], eax |
1920 | or eax, eax ; used to clear zero flag |
- | |
1921 | 1915 | ||
1922 | pusha |
1916 | pusha |
1923 | mov ecx, socket_mutex |
1917 | mov ecx, socket_mutex |
1924 | call mutex_unlock |
1918 | call mutex_unlock |
1925 | popa |
1919 | popa |
1926 | 1920 | ||
1927 | .exit: |
1921 | .exit: |
1928 | pop ebx |
1922 | pop ebx |
1929 | 1923 | ||
1930 | ret |
1924 | ret |
1931 | 1925 | ||
1932 | .not_yet: |
1926 | .not_yet: |
1933 | mov dword[esp+20], ENOTCONN |
1927 | mov dword[esp+20], ENOTCONN |
1934 | mov dword[esp+32], -1 |
1928 | mov dword[esp+32], -1 |
1935 | ret |
1929 | ret |
1936 | 1930 | ||
1937 | 1931 | ||
1938 | ;---------------------------------------------------- |
1932 | ;---------------------------------------------------- |
1939 | ; |
1933 | ; |
1940 | ; SOCKET_free |
1934 | ; SOCKET_free |
1941 | ; |
1935 | ; |
1942 | ; Free socket data memory and remove socket from the list |
1936 | ; Free socket data memory and remove socket from the list |
1943 | ; Caller should lock and unlock socket_mutex |
1937 | ; Caller should lock and unlock socket_mutex |
1944 | ; |
1938 | ; |
1945 | ; IN: eax = socket ptr |
1939 | ; IN: eax = socket ptr |
1946 | ; OUT: / |
1940 | ; OUT: / |
1947 | ; |
1941 | ; |
1948 | ;---------------------------------------------------- |
1942 | ;---------------------------------------------------- |
1949 | align 4 |
1943 | align 4 |
1950 | SOCKET_free: |
1944 | SOCKET_free: |
1951 | 1945 | ||
1952 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax |
1946 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax |
1953 | 1947 | ||
1954 | call SOCKET_check |
1948 | call SOCKET_check |
1955 | jz .error |
1949 | jz .error |
1956 | 1950 | ||
1957 | push ebx |
1951 | push ebx |
1958 | 1952 | ||
1959 | pusha |
1953 | pusha |
1960 | lea ecx, [eax + SOCKET.mutex] |
1954 | lea ecx, [eax + SOCKET.mutex] |
1961 | call mutex_lock |
1955 | call mutex_lock |
1962 | popa |
1956 | popa |
1963 | 1957 | ||
1964 | cmp [eax + SOCKET.Domain], AF_INET4 |
1958 | cmp [eax + SOCKET.Domain], AF_INET4 |
1965 | jnz .no_tcp |
1959 | jnz .no_tcp |
1966 | 1960 | ||
1967 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1961 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1968 | jnz .no_tcp |
1962 | jnz .no_tcp |
1969 | 1963 | ||
1970 | mov ebx, eax |
1964 | mov ebx, eax |
- | 1965 | cmp [ebx + STREAM_SOCKET.rcv.start_ptr], 0 |
|
- | 1966 | je @f |
|
1971 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
1967 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
- | 1968 | @@: |
|
- | 1969 | cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0 |
|
- | 1970 | je @f |
|
1972 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
1971 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
- | 1972 | @@: |
|
1973 | mov eax, ebx |
1973 | mov eax, ebx |
1974 | .no_tcp: |
1974 | .no_tcp: |
1975 | 1975 | ||
1976 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax |
1976 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax |
1977 | push eax ; this will be passed to kernel_free |
1977 | push eax ; this will be passed to kernel_free |
1978 | mov ebx, [eax + SOCKET.NextPtr] |
1978 | mov ebx, [eax + SOCKET.NextPtr] |
1979 | mov eax, [eax + SOCKET.PrevPtr] |
1979 | mov eax, [eax + SOCKET.PrevPtr] |
1980 | 1980 | ||
1981 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1981 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1982 | 1982 | ||
1983 | test eax, eax |
1983 | test eax, eax |
1984 | jz @f |
1984 | jz @f |
1985 | mov [eax + SOCKET.NextPtr], ebx |
1985 | mov [eax + SOCKET.NextPtr], ebx |
1986 | @@: |
1986 | @@: |
1987 | 1987 | ||
1988 | test ebx, ebx |
1988 | test ebx, ebx |
1989 | jz @f |
1989 | jz @f |
1990 | mov [ebx + SOCKET.PrevPtr], eax |
1990 | mov [ebx + SOCKET.PrevPtr], eax |
1991 | @@: |
1991 | @@: |
1992 | 1992 | ||
1993 | call kernel_free |
1993 | call kernel_free |
1994 | pop ebx |
1994 | pop ebx |
1995 | 1995 | ||
1996 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n" |
1996 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n" |
1997 | 1997 | ||
1998 | .error: |
1998 | .error: |
1999 | ret |
1999 | ret |
2000 | 2000 | ||
2001 | ;------------------------------------ |
2001 | ;------------------------------------ |
2002 | ; |
2002 | ; |
2003 | ; SOCKET_fork |
2003 | ; SOCKET_fork |
2004 | ; |
2004 | ; |
2005 | ; Create a child socket |
2005 | ; Create a child socket |
2006 | ; |
2006 | ; |
2007 | ; IN: socket nr in ebx |
2007 | ; IN: socket nr in ebx |
2008 | ; OUT: child socket nr in eax |
2008 | ; OUT: child socket nr in eax |
2009 | ; |
2009 | ; |
2010 | ;----------------------------------- |
2010 | ;----------------------------------- |
2011 | align 4 |
2011 | align 4 |
2012 | SOCKET_fork: |
2012 | SOCKET_fork: |
2013 | 2013 | ||
2014 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_fork: %x\n", ebx |
2014 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_fork: %x\n", ebx |
2015 | 2015 | ||
2016 | ; Exit if backlog queue is full |
2016 | ; Exit if backlog queue is full |
2017 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
2017 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
2018 | cmp ax, [ebx + SOCKET.backlog] |
2018 | cmp ax, [ebx + SOCKET.backlog] |
2019 | jae .fail |
2019 | jae .fail |
2020 | 2020 | ||
2021 | ; Allocate new socket |
2021 | ; Allocate new socket |
2022 | push ebx |
2022 | push ebx |
2023 | call SOCKET_alloc |
2023 | call SOCKET_alloc |
2024 | pop ebx |
2024 | pop ebx |
- | 2025 | test eax, eax |
|
2025 | jz .fail |
2026 | jz .fail |
2026 | 2027 | ||
2027 | push eax |
2028 | push eax |
2028 | mov esi, esp |
2029 | mov esi, esp |
2029 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
2030 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
2030 | pop eax |
2031 | pop eax |
2031 | 2032 | ||
2032 | ; Copy structure from current socket to new |
2033 | ; Copy structure from current socket to new |
2033 | ; We start at PID to preserve the socket num, 2 pointers and mutex |
2034 | ; We start at PID to preserve the socket num, 2 pointers and mutex |
2034 | ; TID will be filled in later |
2035 | ; TID will be filled in later |
2035 | lea esi, [ebx + SOCKET.PID] |
2036 | lea esi, [ebx + SOCKET.PID] |
2036 | lea edi, [eax + SOCKET.PID] |
2037 | lea edi, [eax + SOCKET.PID] |
2037 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
2038 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
2038 | rep movsd |
2039 | rep movsd |
2039 | 2040 | ||
2040 | and [eax + SOCKET.options], not SO_ACCEPTCON |
2041 | and [eax + SOCKET.options], not SO_ACCEPTCON |
2041 | 2042 | ||
2042 | ; Notify owner of parent socket |
2043 | ; Notify owner of parent socket |
2043 | push eax |
2044 | push eax |
2044 | mov eax, ebx |
2045 | mov eax, ebx |
2045 | call SOCKET_notify |
2046 | call SOCKET_notify |
2046 | pop eax |
2047 | pop eax |
2047 | 2048 | ||
2048 | ret |
2049 | ret |
2049 | 2050 | ||
2050 | .fail2: |
2051 | .fail2: |
2051 | add esp, 4+4+4 |
2052 | add esp, 4+4+4 |
2052 | .fail: |
2053 | .fail: |
2053 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_fork: failed\n" |
2054 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_fork: failed\n" |
2054 | xor eax, eax |
2055 | xor eax, eax |
2055 | ret |
2056 | ret |
2056 | 2057 | ||
2057 | 2058 | ||
2058 | ;--------------------------------------------------- |
2059 | ;--------------------------------------------------- |
2059 | ; |
2060 | ; |
2060 | ; SOCKET_num_to_ptr |
2061 | ; SOCKET_num_to_ptr |
2061 | ; |
2062 | ; |
2062 | ; Get socket structure address by its number |
2063 | ; Get socket structure address by its number |
2063 | ; |
2064 | ; |
2064 | ; IN: ecx = socket number |
2065 | ; IN: ecx = socket number |
2065 | ; OUT: eax = 0 on error, socket ptr otherwise |
2066 | ; OUT: eax = 0 on error, socket ptr otherwise |
2066 | ; ZF = set on error |
2067 | ; ZF = set on error |
2067 | ; |
2068 | ; |
2068 | ;--------------------------------------------------- |
2069 | ;--------------------------------------------------- |
2069 | align 4 |
2070 | align 4 |
2070 | SOCKET_num_to_ptr: |
2071 | SOCKET_num_to_ptr: |
2071 | 2072 | ||
2072 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx |
2073 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx |
2073 | 2074 | ||
2074 | pusha |
2075 | pusha |
2075 | mov ecx, socket_mutex |
2076 | mov ecx, socket_mutex |
2076 | call mutex_lock |
2077 | call mutex_lock |
2077 | popa |
2078 | popa |
2078 | 2079 | ||
2079 | mov eax, net_sockets |
2080 | mov eax, net_sockets |
2080 | 2081 | ||
2081 | .next_socket: |
2082 | .next_socket: |
2082 | mov eax, [eax + SOCKET.NextPtr] |
2083 | mov eax, [eax + SOCKET.NextPtr] |
2083 | or eax, eax |
2084 | or eax, eax |
2084 | jz .error |
2085 | jz .error |
2085 | cmp [eax + SOCKET.Number], ecx |
2086 | cmp [eax + SOCKET.Number], ecx |
2086 | jne .next_socket |
2087 | jne .next_socket |
2087 | 2088 | ||
2088 | test eax, eax |
2089 | test eax, eax |
2089 | 2090 | ||
2090 | pusha |
2091 | pusha |
2091 | mov ecx, socket_mutex |
2092 | mov ecx, socket_mutex |
2092 | call mutex_unlock |
2093 | call mutex_unlock |
2093 | popa |
2094 | popa |
2094 | 2095 | ||
2095 | DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax |
2096 | DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax |
2096 | ret |
2097 | ret |
2097 | 2098 | ||
2098 | .error: |
2099 | .error: |
2099 | pusha |
2100 | pusha |
2100 | mov ecx, socket_mutex |
2101 | mov ecx, socket_mutex |
2101 | call mutex_unlock |
2102 | call mutex_unlock |
2102 | popa |
2103 | popa |
2103 | 2104 | ||
- | 2105 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: socket %u not found!\n", eax |
|
2104 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax |
2106 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: caller = 0x%x\n", [esp] |
2105 | ret |
2107 | ret |
2106 | 2108 | ||
2107 | 2109 | ||
2108 | ;--------------------------------------------------- |
2110 | ;--------------------------------------------------- |
2109 | ; |
2111 | ; |
2110 | ; SOCKET_ptr_to_num |
2112 | ; SOCKET_ptr_to_num |
2111 | ; |
2113 | ; |
2112 | ; Get socket number by its address |
2114 | ; Get socket number by its address |
2113 | ; |
2115 | ; |
2114 | ; IN: eax = socket ptr |
2116 | ; IN: eax = socket ptr |
2115 | ; OUT: eax = 0 on error, socket num otherwise |
2117 | ; OUT: eax = 0 on error, socket num otherwise |
2116 | ; ZF = set on error |
2118 | ; ZF = set on error |
2117 | ; |
2119 | ; |
2118 | ;--------------------------------------------------- |
2120 | ;--------------------------------------------------- |
2119 | align 4 |
2121 | align 4 |
2120 | SOCKET_ptr_to_num: |
2122 | SOCKET_ptr_to_num: |
2121 | 2123 | ||
2122 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ptr_to_num: ptr=%x ", eax |
2124 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ptr_to_num: ptr=%x ", eax |
2123 | 2125 | ||
2124 | call SOCKET_check |
2126 | call SOCKET_check |
2125 | jz .error |
2127 | jz .error |
2126 | 2128 | ||
2127 | mov eax, [eax + SOCKET.Number] |
2129 | mov eax, [eax + SOCKET.Number] |
2128 | 2130 | ||
2129 | DEBUGF DEBUG_NETWORK_VERBOSE, "num=%u\n", eax |
2131 | DEBUGF DEBUG_NETWORK_VERBOSE, "num=%u\n", eax |
2130 | ret |
2132 | ret |
2131 | 2133 | ||
2132 | .error: |
2134 | .error: |
2133 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ptr_to_num: not found\n", eax |
2135 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ptr_to_num: not found\n", eax |
2134 | ret |
2136 | ret |
2135 | 2137 | ||
2136 | 2138 | ||
2137 | ;--------------------------------------------------- |
2139 | ;--------------------------------------------------- |
2138 | ; |
2140 | ; |
2139 | ; SOCKET_check |
2141 | ; SOCKET_check |
2140 | ; |
2142 | ; |
2141 | ; checks if the given value is really a socket ptr |
2143 | ; checks if the given value is really a socket ptr |
2142 | ; |
2144 | ; |
2143 | ; IN: eax = socket ptr |
2145 | ; IN: eax = socket ptr |
2144 | ; OUT: eax = 0 on error, unchanged otherwise |
2146 | ; OUT: eax = 0 on error, unchanged otherwise |
2145 | ; ZF = set on error |
2147 | ; ZF = set on error |
2146 | ; |
2148 | ; |
2147 | ;--------------------------------------------------- |
2149 | ;--------------------------------------------------- |
2148 | align 4 |
2150 | align 4 |
2149 | SOCKET_check: |
2151 | SOCKET_check: |
2150 | 2152 | ||
2151 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax |
2153 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax |
2152 | 2154 | ||
2153 | push ebx |
2155 | push ebx |
2154 | mov ebx, net_sockets |
2156 | mov ebx, net_sockets |
2155 | 2157 | ||
2156 | .next_socket: |
2158 | .next_socket: |
2157 | mov ebx, [ebx + SOCKET.NextPtr] |
2159 | mov ebx, [ebx + SOCKET.NextPtr] |
2158 | or ebx, ebx |
2160 | or ebx, ebx |
2159 | jz .done |
2161 | jz .done |
2160 | cmp ebx, eax |
2162 | cmp ebx, eax |
2161 | jnz .next_socket |
2163 | jnz .next_socket |
2162 | 2164 | ||
2163 | .done: |
2165 | .done: |
2164 | mov eax, ebx |
2166 | mov eax, ebx |
2165 | test eax, eax |
2167 | test eax, eax |
2166 | pop ebx |
2168 | pop ebx |
2167 | 2169 | ||
2168 | ret |
2170 | ret |
2169 | 2171 | ||
2170 | 2172 | ||
2171 | 2173 | ||
2172 | ;--------------------------------------------------- |
2174 | ;--------------------------------------------------- |
2173 | ; |
2175 | ; |
2174 | ; SOCKET_check_owner |
2176 | ; SOCKET_check_owner |
2175 | ; |
2177 | ; |
2176 | ; checks if the caller application owns the socket |
2178 | ; checks if the caller application owns the socket |
2177 | ; |
2179 | ; |
2178 | ; IN: eax = socket ptr |
2180 | ; IN: eax = socket ptr |
2179 | ; OUT: ZF = true/false |
2181 | ; OUT: ZF = true/false |
2180 | ; |
2182 | ; |
2181 | ;--------------------------------------------------- |
2183 | ;--------------------------------------------------- |
2182 | align 4 |
2184 | align 4 |
2183 | SOCKET_check_owner: |
2185 | SOCKET_check_owner: |
2184 | 2186 | ||
2185 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_owner: %x\n", eax |
2187 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_owner: %x\n", eax |
2186 | 2188 | ||
2187 | push ebx |
2189 | push ebx |
2188 | mov ebx, [TASK_BASE] |
2190 | mov ebx, [TASK_BASE] |
2189 | mov ebx, [ebx + TASKDATA.pid] |
2191 | mov ebx, [ebx + TASKDATA.pid] |
2190 | cmp [eax + SOCKET.PID], ebx |
2192 | cmp [eax + SOCKET.PID], ebx |
2191 | pop ebx |
2193 | pop ebx |
2192 | 2194 | ||
2193 | ret |
2195 | ret |
2194 | 2196 | ||
2195 | 2197 | ||
2196 | 2198 | ||
2197 | 2199 | ||
2198 | ;------------------------------------------------------ |
2200 | ;------------------------------------------------------ |
2199 | ; |
2201 | ; |
2200 | ; SOCKET_process_end |
2202 | ; SOCKET_process_end |
2201 | ; |
2203 | ; |
2202 | ; Kernel calls this function when a certain process ends |
2204 | ; Kernel calls this function when a certain process ends |
2203 | ; This function will check if the process had any open sockets |
2205 | ; This function will check if the process had any open sockets |
2204 | ; And update them accordingly (clean up) |
2206 | ; And update them accordingly (clean up) |
2205 | ; |
2207 | ; |
2206 | ; IN: edx = pid |
2208 | ; IN: edx = pid |
2207 | ; OUT: / |
2209 | ; OUT: / |
2208 | ; |
2210 | ; |
2209 | ;------------------------------------------------------ |
2211 | ;------------------------------------------------------ |
2210 | align 4 |
2212 | align 4 |
2211 | SOCKET_process_end: |
2213 | SOCKET_process_end: |
- | 2214 | ||
- | 2215 | ret ; FIXME |
|
2212 | 2216 | ||
2213 | cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all? |
2217 | cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all? |
2214 | je .quickret ; nope, exit immediately |
2218 | je .quickret ; nope, exit immediately |
2215 | 2219 | ||
2216 | ; TODO: run the following code in another thread, to avoid deadlock |
2220 | ; TODO: run the following code in another thread, to avoid deadlock |
2217 | 2221 | ||
2218 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx |
2222 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx |
2219 | 2223 | ||
2220 | pusha |
2224 | pusha |
2221 | mov ecx, socket_mutex |
2225 | mov ecx, socket_mutex |
2222 | call mutex_lock |
2226 | call mutex_lock |
2223 | popa |
2227 | popa |
2224 | 2228 | ||
2225 | push ebx |
2229 | push ebx |
2226 | mov ebx, net_sockets |
2230 | mov ebx, net_sockets |
2227 | 2231 | ||
2228 | .next_socket: |
2232 | .next_socket: |
2229 | mov ebx, [ebx + SOCKET.NextPtr] |
2233 | mov ebx, [ebx + SOCKET.NextPtr] |
2230 | .next_socket_test: |
2234 | .next_socket_test: |
2231 | test ebx, ebx |
2235 | test ebx, ebx |
2232 | jz .done |
2236 | jz .done |
2233 | 2237 | ||
2234 | cmp [ebx + SOCKET.PID], edx |
2238 | cmp [ebx + SOCKET.PID], edx |
2235 | jne .next_socket |
2239 | jne .next_socket |
2236 | 2240 | ||
2237 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx |
2241 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx |
2238 | 2242 | ||
2239 | mov [ebx + SOCKET.PID], 0 |
2243 | mov [ebx + SOCKET.PID], 0 |
2240 | mov eax, ebx |
2244 | mov eax, ebx |
2241 | mov ebx, [ebx + SOCKET.NextPtr] |
2245 | mov ebx, [ebx + SOCKET.NextPtr] |
2242 | 2246 | ||
2243 | pusha |
2247 | pusha |
2244 | cmp [eax + SOCKET.Domain], AF_INET4 |
2248 | cmp [eax + SOCKET.Domain], AF_INET4 |
2245 | jne .free |
2249 | jne .free |
2246 | 2250 | ||
2247 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
2251 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
2248 | jne .free |
2252 | jne .free |
2249 | 2253 | ||
2250 | call TCP_disconnect |
2254 | call TCP_disconnect |
2251 | jmp .closed |
2255 | jmp .closed |
2252 | 2256 | ||
2253 | .free: |
2257 | .free: |
2254 | call SOCKET_free |
2258 | call SOCKET_free |
2255 | 2259 | ||
2256 | .closed: |
2260 | .closed: |
2257 | popa |
2261 | popa |
2258 | jmp .next_socket_test |
2262 | jmp .next_socket_test |
2259 | 2263 | ||
2260 | .done: |
2264 | .done: |
2261 | pop ebx |
2265 | pop ebx |
2262 | 2266 | ||
2263 | pusha |
2267 | pusha |
2264 | mov ecx, socket_mutex |
2268 | mov ecx, socket_mutex |
2265 | call mutex_unlock |
2269 | call mutex_unlock |
2266 | popa |
2270 | popa |
2267 | 2271 | ||
2268 | .quickret: |
2272 | .quickret: |
2269 | ret |
2273 | ret |
2270 | 2274 | ||
2271 | 2275 | ||
2272 | 2276 | ||
2273 | 2277 | ||
2274 | ;----------------------------------------------------------------- |
2278 | ;----------------------------------------------------------------- |
2275 | ; |
2279 | ; |
2276 | ; SOCKET_is_connecting |
2280 | ; SOCKET_is_connecting |
2277 | ; |
2281 | ; |
2278 | ; IN: eax = socket ptr |
2282 | ; IN: eax = socket ptr |
2279 | ; OUT: / |
2283 | ; OUT: / |
2280 | ; |
2284 | ; |
2281 | ;----------------------------------------------------------------- |
2285 | ;----------------------------------------------------------------- |
2282 | 2286 | ||
2283 | align 4 |
2287 | align 4 |
2284 | SOCKET_is_connecting: |
2288 | SOCKET_is_connecting: |
2285 | 2289 | ||
2286 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax |
2290 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax |
2287 | 2291 | ||
2288 | and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2292 | and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2289 | or [eax + SOCKET.state], SS_ISCONNECTING |
2293 | or [eax + SOCKET.state], SS_ISCONNECTING |
2290 | 2294 | ||
2291 | ret |
2295 | ret |
2292 | 2296 | ||
2293 | 2297 | ||
2294 | 2298 | ||
2295 | ;----------------------------------------------------------------- |
2299 | ;----------------------------------------------------------------- |
2296 | ; |
2300 | ; |
2297 | ; SOCKET_is_connected |
2301 | ; SOCKET_is_connected |
2298 | ; |
2302 | ; |
2299 | ; IN: eax = socket ptr |
2303 | ; IN: eax = socket ptr |
2300 | ; OUT: / |
2304 | ; OUT: / |
2301 | ; |
2305 | ; |
2302 | ;----------------------------------------------------------------- |
2306 | ;----------------------------------------------------------------- |
2303 | 2307 | ||
2304 | align 4 |
2308 | align 4 |
2305 | SOCKET_is_connected: |
2309 | SOCKET_is_connected: |
2306 | 2310 | ||
2307 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax |
2311 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax |
2308 | 2312 | ||
2309 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2313 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2310 | or [eax + SOCKET.state], SS_ISCONNECTED |
2314 | or [eax + SOCKET.state], SS_ISCONNECTED |
2311 | 2315 | ||
2312 | jmp SOCKET_notify |
2316 | jmp SOCKET_notify |
2313 | 2317 | ||
2314 | 2318 | ||
2315 | 2319 | ||
2316 | 2320 | ||
2317 | ;----------------------------------------------------------------- |
2321 | ;----------------------------------------------------------------- |
2318 | ; |
2322 | ; |
2319 | ; SOCKET_is_disconnecting |
2323 | ; SOCKET_is_disconnecting |
2320 | ; |
2324 | ; |
2321 | ; IN: eax = socket ptr |
2325 | ; IN: eax = socket ptr |
2322 | ; OUT: / |
2326 | ; OUT: / |
2323 | ; |
2327 | ; |
2324 | ;----------------------------------------------------------------- |
2328 | ;----------------------------------------------------------------- |
2325 | 2329 | ||
2326 | align 4 |
2330 | align 4 |
2327 | SOCKET_is_disconnecting: |
2331 | SOCKET_is_disconnecting: |
2328 | 2332 | ||
2329 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax |
2333 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax |
2330 | 2334 | ||
2331 | and [eax + SOCKET.state], not (SS_ISCONNECTING) |
2335 | and [eax + SOCKET.state], not (SS_ISCONNECTING) |
2332 | or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
2336 | or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
2333 | 2337 | ||
2334 | jmp SOCKET_notify |
2338 | jmp SOCKET_notify |
2335 | 2339 | ||
2336 | 2340 | ||
2337 | 2341 | ||
2338 | ;----------------------------------------------------------------- |
2342 | ;----------------------------------------------------------------- |
2339 | ; |
2343 | ; |
2340 | ; SOCKET_is_disconnected |
2344 | ; SOCKET_is_disconnected |
2341 | ; |
2345 | ; |
2342 | ; IN: eax = socket ptr |
2346 | ; IN: eax = socket ptr |
2343 | ; OUT: / |
2347 | ; OUT: / |
2344 | ; |
2348 | ; |
2345 | ;----------------------------------------------------------------- |
2349 | ;----------------------------------------------------------------- |
2346 | 2350 | ||
2347 | align 4 |
2351 | align 4 |
2348 | SOCKET_is_disconnected: |
2352 | SOCKET_is_disconnected: |
2349 | 2353 | ||
2350 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax |
2354 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax |
2351 | 2355 | ||
2352 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
2356 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
2353 | or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE |
2357 | or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE |
2354 | 2358 | ||
2355 | 2359 | ||
2356 | jmp SOCKET_notify |
2360 | jmp SOCKET_notify |
2357 | 2361 | ||
2358 | 2362 | ||
2359 | 2363 | ||
2360 | ;----------------------------------------------------------------- |
2364 | ;----------------------------------------------------------------- |
2361 | ; |
2365 | ; |
2362 | ; SOCKET_cant_recv_more |
2366 | ; SOCKET_cant_recv_more |
2363 | ; |
2367 | ; |
2364 | ; IN: eax = socket ptr |
2368 | ; IN: eax = socket ptr |
2365 | ; OUT: / |
2369 | ; OUT: / |
2366 | ; |
2370 | ; |
2367 | ;----------------------------------------------------------------- |
2371 | ;----------------------------------------------------------------- |
2368 | 2372 | ||
2369 | align 4 |
2373 | align 4 |
2370 | SOCKET_cant_recv_more: |
2374 | SOCKET_cant_recv_more: |
2371 | 2375 | ||
2372 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax |
2376 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax |
2373 | 2377 | ||
2374 | or [eax + SOCKET.state], SS_CANTRCVMORE |
2378 | or [eax + SOCKET.state], SS_CANTRCVMORE |
2375 | 2379 | ||
2376 | call SOCKET_notify |
2380 | call SOCKET_notify |
2377 | 2381 | ||
2378 | ret |
2382 | ret |
2379 | 2383 | ||
2380 | 2384 | ||
2381 | 2385 | ||
2382 | ;----------------------------------------------------------------- |
2386 | ;----------------------------------------------------------------- |
2383 | ; |
2387 | ; |
2384 | ; SOCKET_cant_send_more |
2388 | ; SOCKET_cant_send_more |
2385 | ; |
2389 | ; |
2386 | ; IN: eax = socket ptr |
2390 | ; IN: eax = socket ptr |
2387 | ; OUT: / |
2391 | ; OUT: / |
2388 | ; |
2392 | ; |
2389 | ;----------------------------------------------------------------- |
2393 | ;----------------------------------------------------------------- |
2390 | 2394 | ||
2391 | align 4 |
2395 | align 4 |
2392 | SOCKET_cant_send_more: |
2396 | SOCKET_cant_send_more: |
2393 | 2397 | ||
2394 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax |
2398 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax |
2395 | 2399 | ||
2396 | or [eax + SOCKET.state], SS_CANTSENDMORE |
2400 | or [eax + SOCKET.state], SS_CANTSENDMORE |
2397 | mov [eax + SOCKET.snd_proc], .notconn |
2401 | mov [eax + SOCKET.snd_proc], .notconn |
2398 | 2402 | ||
2399 | call SOCKET_notify |
2403 | call SOCKET_notify |
2400 | 2404 | ||
2401 | ret |
2405 | ret |
2402 | 2406 | ||
2403 | .notconn: |
2407 | .notconn: |
2404 | mov dword[esp+20], ENOTCONN |
2408 | mov dword[esp+20], ENOTCONN |
2405 | mov dword[esp+32], -1 |
2409 | mov dword[esp+32], -1 |
2406 | ret |
2410 | ret |