Rev 4457 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4457 | Rev 4587 | ||
---|---|---|---|
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: 3514 $ |
18 | $Revision: 3514 $ |
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 |
1223 | 1226 | ||
1224 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1227 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1225 | call SOCKET_ring_create |
1228 | call SOCKET_ring_create |
1226 | pop eax |
1229 | pop eax |
1227 | 1230 | ||
1228 | ret |
1231 | ret |
1229 | 1232 | ||
1230 | .nomem2: |
1233 | .nomem2: |
1231 | mov eax, ebx |
1234 | mov eax, ebx |
1232 | call SOCKET_free |
1235 | call SOCKET_free |
1233 | .nomem1: |
1236 | .nomem1: |
1234 | mov dword[esp+32], -1 |
1237 | mov dword[esp+32], -1 |
1235 | mov dword[esp+28], ENOMEM |
1238 | mov dword[esp+28], ENOMEM |
1236 | ret |
1239 | ret |
1237 | 1240 | ||
1238 | 1241 | ||
1239 | 1242 | ||
1240 | ;----------------------------------------------------------------- |
1243 | ;----------------------------------------------------------------- |
1241 | ; |
1244 | ; |
1242 | ; SOCKET_debug |
1245 | ; SOCKET_debug |
1243 | ; |
1246 | ; |
1244 | ; Copies socket variables to application buffer |
1247 | ; Copies socket variables to application buffer |
1245 | ; |
1248 | ; |
1246 | ; IN: ecx = socket number |
1249 | ; IN: ecx = socket number |
1247 | ; edx = pointer to buffer |
1250 | ; edx = pointer to buffer |
1248 | ; |
1251 | ; |
1249 | ; OUT: -1 on error |
1252 | ; OUT: -1 on error |
1250 | ;----------------------------------------------------------------- |
1253 | ;----------------------------------------------------------------- |
1251 | align 4 |
1254 | align 4 |
1252 | SOCKET_debug: |
1255 | SOCKET_debug: |
1253 | 1256 | ||
1254 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_debug\n" |
1257 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_debug\n" |
1255 | 1258 | ||
1256 | mov edi, edx |
1259 | mov edi, edx |
1257 | 1260 | ||
1258 | test ecx, ecx |
1261 | test ecx, ecx |
1259 | jz .returnall |
1262 | jz .returnall |
1260 | 1263 | ||
1261 | call SOCKET_num_to_ptr |
1264 | call SOCKET_num_to_ptr |
1262 | jz .invalid |
1265 | jz .invalid |
1263 | 1266 | ||
1264 | mov esi, eax |
1267 | mov esi, eax |
1265 | mov ecx, SOCKETBUFFSIZE/4 |
1268 | mov ecx, SOCKETBUFFSIZE/4 |
1266 | rep movsd |
1269 | rep movsd |
1267 | 1270 | ||
1268 | mov dword[esp+32], 0 |
1271 | mov dword[esp+32], 0 |
1269 | ret |
1272 | ret |
1270 | 1273 | ||
1271 | .returnall: |
1274 | .returnall: |
1272 | mov ebx, net_sockets |
1275 | mov ebx, net_sockets |
1273 | .next_socket: |
1276 | .next_socket: |
1274 | mov ebx, [ebx + SOCKET.NextPtr] |
1277 | mov ebx, [ebx + SOCKET.NextPtr] |
1275 | test ebx, ebx |
1278 | test ebx, ebx |
1276 | jz .done |
1279 | jz .done |
1277 | mov eax, [ebx + SOCKET.Number] |
1280 | mov eax, [ebx + SOCKET.Number] |
1278 | stosd |
1281 | stosd |
1279 | jmp .next_socket |
1282 | jmp .next_socket |
1280 | .done: |
1283 | .done: |
1281 | xor eax, eax |
1284 | xor eax, eax |
1282 | stosd |
1285 | stosd |
1283 | mov dword[esp+32], eax |
1286 | mov dword[esp+32], eax |
1284 | ret |
1287 | ret |
1285 | 1288 | ||
1286 | .invalid: |
1289 | .invalid: |
1287 | mov dword[esp+32], -1 |
1290 | mov dword[esp+32], -1 |
1288 | mov dword[esp+28], EINVAL |
1291 | mov dword[esp+28], EINVAL |
1289 | ret |
1292 | ret |
1290 | 1293 | ||
1291 | 1294 | ||
1292 | ;----------------------------------------------------------------- |
1295 | ;----------------------------------------------------------------- |
1293 | ; |
1296 | ; |
1294 | ; SOCKET_find_port |
1297 | ; SOCKET_find_port |
1295 | ; |
1298 | ; |
1296 | ; Fills in the local port number for TCP and UDP sockets |
1299 | ; Fills in the local port number for TCP and UDP sockets |
1297 | ; This procedure always works because the number of sockets is |
1300 | ; This procedure always works because the number of sockets is |
1298 | ; limited to a smaller number then the number of possible ports |
1301 | ; limited to a smaller number then the number of possible ports |
1299 | ; |
1302 | ; |
1300 | ; IN: eax = socket pointer |
1303 | ; IN: eax = socket pointer |
1301 | ; OUT: / |
1304 | ; OUT: / |
1302 | ; |
1305 | ; |
1303 | ;----------------------------------------------------------------- |
1306 | ;----------------------------------------------------------------- |
1304 | align 4 |
1307 | align 4 |
1305 | SOCKET_find_port: |
1308 | SOCKET_find_port: |
1306 | 1309 | ||
1307 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_find_port\n" |
1310 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_find_port\n" |
1308 | 1311 | ||
1309 | push ebx esi ecx |
1312 | push ebx esi ecx |
1310 | 1313 | ||
1311 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1314 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1312 | je .udp |
1315 | je .udp |
1313 | 1316 | ||
1314 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1317 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1315 | je .tcp |
1318 | je .tcp |
1316 | 1319 | ||
1317 | pop ecx esi ebx |
1320 | pop ecx esi ebx |
1318 | ret |
1321 | ret |
1319 | 1322 | ||
1320 | .udp: |
1323 | .udp: |
1321 | mov bx, [last_UDP_port] |
1324 | mov bx, [last_UDP_port] |
1322 | call .findit |
1325 | call .findit |
1323 | mov [last_UDP_port], bx |
1326 | mov [last_UDP_port], bx |
1324 | 1327 | ||
1325 | pop ecx esi ebx |
1328 | pop ecx esi ebx |
1326 | ret |
1329 | ret |
1327 | 1330 | ||
1328 | .tcp: |
1331 | .tcp: |
1329 | mov bx, [last_TCP_port] |
1332 | mov bx, [last_TCP_port] |
1330 | call .findit |
1333 | call .findit |
1331 | mov [last_TCP_port], bx |
1334 | mov [last_TCP_port], bx |
1332 | 1335 | ||
1333 | pop ecx esi ebx |
1336 | pop ecx esi ebx |
1334 | ret |
1337 | ret |
1335 | 1338 | ||
1336 | 1339 | ||
1337 | .restart: |
1340 | .restart: |
1338 | mov bx, MIN_EPHEMERAL_PORT_N |
1341 | mov bx, MIN_EPHEMERAL_PORT_N |
1339 | .findit: |
1342 | .findit: |
1340 | cmp bx, MAX_EPHEMERAL_PORT_N |
1343 | cmp bx, MAX_EPHEMERAL_PORT_N |
1341 | je .restart |
1344 | je .restart |
1342 | 1345 | ||
1343 | add bh, 1 |
1346 | add bh, 1 |
1344 | adc bl, 0 |
1347 | adc bl, 0 |
1345 | 1348 | ||
1346 | call SOCKET_check_port |
1349 | call SOCKET_check_port |
1347 | jz .findit |
1350 | jz .findit |
1348 | ret |
1351 | ret |
1349 | 1352 | ||
1350 | 1353 | ||
1351 | 1354 | ||
1352 | ;----------------------------------------------------------------- |
1355 | ;----------------------------------------------------------------- |
1353 | ; |
1356 | ; |
1354 | ; SOCKET_check_port (to be used with AF_INET only!) |
1357 | ; SOCKET_check_port (to be used with AF_INET only!) |
1355 | ; |
1358 | ; |
1356 | ; Checks if a local port number is unused |
1359 | ; Checks if a local port number is unused |
1357 | ; If the proposed port number is unused, it is filled in in the socket structure |
1360 | ; If the proposed port number is unused, it is filled in in the socket structure |
1358 | ; |
1361 | ; |
1359 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1362 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1360 | ; bx = proposed socket number (network byte order) |
1363 | ; bx = proposed socket number (network byte order) |
1361 | ; |
1364 | ; |
1362 | ; OUT: ZF = set on error |
1365 | ; OUT: ZF = set on error |
1363 | ; |
1366 | ; |
1364 | ;----------------------------------------------------------------- |
1367 | ;----------------------------------------------------------------- |
1365 | align 4 |
1368 | align 4 |
1366 | SOCKET_check_port: |
1369 | SOCKET_check_port: |
1367 | 1370 | ||
1368 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: " |
1371 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: " |
1369 | 1372 | ||
1370 | pusha |
1373 | pusha |
1371 | mov ecx, socket_mutex |
1374 | mov ecx, socket_mutex |
1372 | call mutex_lock |
1375 | call mutex_lock |
1373 | popa |
1376 | popa |
1374 | 1377 | ||
1375 | mov ecx, [eax + SOCKET.Protocol] |
1378 | mov ecx, [eax + SOCKET.Protocol] |
1376 | mov edx, [eax + IP_SOCKET.LocalIP] |
1379 | mov edx, [eax + IP_SOCKET.LocalIP] |
1377 | mov esi, net_sockets |
1380 | mov esi, net_sockets |
1378 | 1381 | ||
1379 | .next_socket: |
1382 | .next_socket: |
1380 | mov esi, [esi + SOCKET.NextPtr] |
1383 | mov esi, [esi + SOCKET.NextPtr] |
1381 | or esi, esi |
1384 | or esi, esi |
1382 | jz .port_ok |
1385 | jz .port_ok |
1383 | 1386 | ||
1384 | cmp [esi + SOCKET.Protocol], ecx |
1387 | cmp [esi + SOCKET.Protocol], ecx |
1385 | jne .next_socket |
1388 | jne .next_socket |
1386 | 1389 | ||
1387 | cmp [esi + IP_SOCKET.LocalIP], edx |
1390 | cmp [esi + IP_SOCKET.LocalIP], edx |
1388 | jne .next_socket |
1391 | jne .next_socket |
1389 | 1392 | ||
1390 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1393 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1391 | jne .next_socket |
1394 | jne .next_socket |
1392 | 1395 | ||
1393 | pusha |
1396 | pusha |
1394 | mov ecx, socket_mutex |
1397 | mov ecx, socket_mutex |
1395 | call mutex_unlock |
1398 | call mutex_unlock |
1396 | popa |
1399 | popa |
1397 | 1400 | ||
1398 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf |
1401 | 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 |
1402 | ret |
1400 | 1403 | ||
1401 | .port_ok: |
1404 | .port_ok: |
1402 | pusha |
1405 | pusha |
1403 | mov ecx, socket_mutex |
1406 | mov ecx, socket_mutex |
1404 | call mutex_unlock |
1407 | call mutex_unlock |
1405 | popa |
1408 | popa |
1406 | 1409 | ||
1407 | DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf |
1410 | 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 |
1411 | mov [eax + UDP_SOCKET.LocalPort], bx |
1409 | or bx, bx ; clear the zero-flag |
1412 | or bx, bx ; clear the zero-flag |
1410 | ret |
1413 | ret |
1411 | 1414 | ||
1412 | 1415 | ||
1413 | 1416 | ||
1414 | ;----------------------------------------------------------------- |
1417 | ;----------------------------------------------------------------- |
1415 | ; |
1418 | ; |
1416 | ; SOCKET_input |
1419 | ; SOCKET_input |
1417 | ; |
1420 | ; |
1418 | ; Updates a (stateless) socket with received data |
1421 | ; Updates a (stateless) socket with received data |
1419 | ; |
1422 | ; |
1420 | ; Note: the mutex should already be set ! |
1423 | ; Note: the mutex should already be set ! |
1421 | ; |
1424 | ; |
1422 | ; IN: eax = socket ptr |
1425 | ; IN: eax = socket ptr |
1423 | ; ecx = data size |
1426 | ; ecx = data size |
1424 | ; esi = ptr to data |
1427 | ; esi = ptr to data |
1425 | ; [esp] = ptr to buf |
1428 | ; [esp] = ptr to buf |
1426 | ; [esp + 4] = buf size |
1429 | ; [esp + 4] = buf size |
1427 | ; |
1430 | ; |
1428 | ; OUT: / |
1431 | ; OUT: / |
1429 | ; |
1432 | ; |
1430 | ;----------------------------------------------------------------- |
1433 | ;----------------------------------------------------------------- |
1431 | align 4 |
1434 | align 4 |
1432 | SOCKET_input: |
1435 | SOCKET_input: |
1433 | 1436 | ||
1434 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1437 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1435 | 1438 | ||
1436 | mov [esp+4], ecx |
1439 | mov [esp+4], ecx |
1437 | push esi |
1440 | push esi |
1438 | mov esi, esp |
1441 | mov esi, esp |
1439 | 1442 | ||
1440 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1443 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1441 | 1444 | ||
1442 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: success\n" |
1445 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: success\n" |
1443 | add esp, sizeof.socket_queue_entry |
1446 | add esp, sizeof.socket_queue_entry |
1444 | 1447 | ||
1445 | pusha |
1448 | pusha |
1446 | lea ecx, [eax + SOCKET.mutex] |
1449 | lea ecx, [eax + SOCKET.mutex] |
1447 | call mutex_unlock |
1450 | call mutex_unlock |
1448 | popa |
1451 | popa |
1449 | 1452 | ||
1450 | jmp SOCKET_notify |
1453 | jmp SOCKET_notify |
1451 | 1454 | ||
1452 | .full: |
1455 | .full: |
1453 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket %x is full!\n", eax |
1456 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket %x is full!\n", eax |
1454 | 1457 | ||
1455 | pusha |
1458 | pusha |
1456 | lea ecx, [eax + SOCKET.mutex] |
1459 | lea ecx, [eax + SOCKET.mutex] |
1457 | call mutex_unlock |
1460 | call mutex_unlock |
1458 | popa |
1461 | popa |
1459 | 1462 | ||
1460 | call NET_packet_free |
1463 | call NET_packet_free |
1461 | add esp, 8 |
1464 | add esp, 8 |
1462 | 1465 | ||
1463 | ret |
1466 | ret |
1464 | 1467 | ||
1465 | 1468 | ||
1466 | ;-------------------------- |
1469 | ;-------------------------- |
1467 | ; |
1470 | ; |
1468 | ; eax = ptr to ring struct (just a buffer of the right size) |
1471 | ; eax = ptr to ring struct (just a buffer of the right size) |
1469 | ; |
1472 | ; |
1470 | align 4 |
1473 | align 4 |
1471 | SOCKET_ring_create: |
1474 | SOCKET_ring_create: |
1472 | 1475 | ||
1473 | push esi |
1476 | push esi |
1474 | mov esi, eax |
1477 | mov esi, eax |
1475 | 1478 | ||
1476 | push edx |
1479 | push edx |
1477 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1480 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1478 | pop edx |
1481 | pop edx |
1479 | 1482 | ||
1480 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax |
1483 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax |
1481 | 1484 | ||
1482 | pusha |
1485 | pusha |
1483 | lea ecx, [esi + RING_BUFFER.mutex] |
1486 | lea ecx, [esi + RING_BUFFER.mutex] |
1484 | call mutex_init |
1487 | call mutex_init |
1485 | popa |
1488 | popa |
1486 | 1489 | ||
1487 | mov [esi + RING_BUFFER.start_ptr], eax |
1490 | mov [esi + RING_BUFFER.start_ptr], eax |
1488 | mov [esi + RING_BUFFER.write_ptr], eax |
1491 | mov [esi + RING_BUFFER.write_ptr], eax |
1489 | mov [esi + RING_BUFFER.read_ptr], eax |
1492 | mov [esi + RING_BUFFER.read_ptr], eax |
1490 | mov [esi + RING_BUFFER.size], 0 |
1493 | mov [esi + RING_BUFFER.size], 0 |
1491 | add eax, SOCKET_MAXDATA |
1494 | add eax, SOCKET_MAXDATA |
1492 | mov [esi + RING_BUFFER.end_ptr], eax |
1495 | mov [esi + RING_BUFFER.end_ptr], eax |
1493 | mov eax, esi |
1496 | mov eax, esi |
1494 | pop esi |
1497 | pop esi |
1495 | 1498 | ||
1496 | ret |
1499 | ret |
1497 | 1500 | ||
1498 | ;----------------------------------------------------------------- |
1501 | ;----------------------------------------------------------------- |
1499 | ; |
1502 | ; |
1500 | ; SOCKET_ring_write |
1503 | ; SOCKET_ring_write |
1501 | ; |
1504 | ; |
1502 | ; Adds data to a stream socket, and updates write pointer and size |
1505 | ; Adds data to a stream socket, and updates write pointer and size |
1503 | ; |
1506 | ; |
1504 | ; IN: eax = ptr to ring struct |
1507 | ; IN: eax = ptr to ring struct |
1505 | ; ecx = data size |
1508 | ; ecx = data size |
1506 | ; esi = ptr to data |
1509 | ; esi = ptr to data |
1507 | ; |
1510 | ; |
1508 | ; OUT: ecx = number of bytes stored |
1511 | ; OUT: ecx = number of bytes stored |
1509 | ; |
1512 | ; |
1510 | ;----------------------------------------------------------------- |
1513 | ;----------------------------------------------------------------- |
1511 | align 4 |
1514 | align 4 |
1512 | SOCKET_ring_write: |
1515 | SOCKET_ring_write: |
1513 | 1516 | ||
1514 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1517 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1515 | 1518 | ||
1516 | ; lock mutex |
1519 | ; lock mutex |
1517 | pusha |
1520 | pusha |
1518 | lea ecx, [eax + RING_BUFFER.mutex] |
1521 | lea ecx, [eax + RING_BUFFER.mutex] |
1519 | call mutex_lock ; TODO: check what registers this function actually destroys |
1522 | call mutex_lock ; TODO: check what registers this function actually destroys |
1520 | popa |
1523 | popa |
1521 | 1524 | ||
1522 | ; calculate available size |
1525 | ; calculate available size |
1523 | mov edi, SOCKET_MAXDATA |
1526 | mov edi, SOCKET_MAXDATA |
1524 | sub edi, [eax + RING_BUFFER.size] ; available buffer size in edi |
1527 | sub edi, [eax + RING_BUFFER.size] ; available buffer size in edi |
1525 | cmp ecx, edi |
1528 | cmp ecx, edi |
1526 | jbe .copy |
1529 | jbe .copy |
1527 | mov ecx, edi |
1530 | mov ecx, edi |
1528 | .copy: |
1531 | .copy: |
1529 | mov edi, [eax + RING_BUFFER.write_ptr] |
1532 | 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 |
1533 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
1531 | 1534 | ||
1532 | ; update write ptr |
1535 | ; update write ptr |
1533 | push edi |
1536 | push edi |
1534 | add edi, ecx |
1537 | add edi, ecx |
1535 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1538 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1536 | jb @f |
1539 | jb @f |
1537 | sub edi, SOCKET_MAXDATA ; WRAP |
1540 | sub edi, SOCKET_MAXDATA ; WRAP |
1538 | @@: |
1541 | @@: |
1539 | mov [eax + RING_BUFFER.write_ptr], edi |
1542 | mov [eax + RING_BUFFER.write_ptr], edi |
1540 | pop edi |
1543 | pop edi |
1541 | 1544 | ||
1542 | ; update size |
1545 | ; update size |
1543 | add [eax + RING_BUFFER.size], ecx |
1546 | add [eax + RING_BUFFER.size], ecx |
1544 | 1547 | ||
1545 | ; copy the data |
1548 | ; copy the data |
1546 | push ecx |
1549 | push ecx |
1547 | shr ecx, 1 |
1550 | shr ecx, 1 |
1548 | jnc .nb |
1551 | jnc .nb |
1549 | movsb |
1552 | movsb |
1550 | .nb: |
1553 | .nb: |
1551 | shr ecx, 1 |
1554 | shr ecx, 1 |
1552 | jnc .nw |
1555 | jnc .nw |
1553 | movsw |
1556 | movsw |
1554 | .nw: |
1557 | .nw: |
1555 | test ecx, ecx |
1558 | test ecx, ecx |
1556 | jz .nd |
1559 | jz .nd |
1557 | rep movsd |
1560 | rep movsd |
1558 | .nd: |
1561 | .nd: |
1559 | pop ecx |
1562 | pop ecx |
1560 | 1563 | ||
1561 | ; unlock mutex |
1564 | ; unlock mutex |
1562 | pusha |
1565 | pusha |
1563 | lea ecx, [eax + RING_BUFFER.mutex] |
1566 | lea ecx, [eax + RING_BUFFER.mutex] |
1564 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1567 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1565 | popa |
1568 | popa |
1566 | 1569 | ||
1567 | ret |
1570 | ret |
1568 | 1571 | ||
1569 | ;----------------------------------------------------------------- |
1572 | ;----------------------------------------------------------------- |
1570 | ; |
1573 | ; |
1571 | ; SOCKET_ring_read |
1574 | ; SOCKET_ring_read |
1572 | ; |
1575 | ; |
1573 | ; IN: eax = ring struct ptr |
1576 | ; IN: eax = ring struct ptr |
1574 | ; ecx = bytes to read |
1577 | ; ecx = bytes to read |
1575 | ; edx = offset |
1578 | ; edx = offset |
1576 | ; edi = ptr to buffer start |
1579 | ; edi = ptr to buffer start |
1577 | ; |
1580 | ; |
1578 | ; OUT: eax = unchanged |
1581 | ; OUT: eax = unchanged |
1579 | ; ecx = number of bytes read (0 on error) |
1582 | ; ecx = number of bytes read (0 on error) |
1580 | ; edx = destroyed |
1583 | ; edx = destroyed |
1581 | ; esi = destroyed |
1584 | ; esi = destroyed |
1582 | ; edi = ptr to buffer end |
1585 | ; edi = ptr to buffer end |
1583 | ; |
1586 | ; |
1584 | ;----------------------------------------------------------------- |
1587 | ;----------------------------------------------------------------- |
1585 | align 4 |
1588 | align 4 |
1586 | SOCKET_ring_read: |
1589 | SOCKET_ring_read: |
1587 | 1590 | ||
1588 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1591 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1589 | 1592 | ||
1590 | pusha |
1593 | pusha |
1591 | lea ecx, [eax + RING_BUFFER.mutex] |
1594 | lea ecx, [eax + RING_BUFFER.mutex] |
1592 | call mutex_lock ; TODO: check what registers this function actually destroys |
1595 | call mutex_lock ; TODO: check what registers this function actually destroys |
1593 | popa |
1596 | popa |
1594 | 1597 | ||
1595 | mov esi, [eax + RING_BUFFER.read_ptr] |
1598 | mov esi, [eax + RING_BUFFER.read_ptr] |
1596 | add esi, edx ; esi = start_ptr + offset |
1599 | add esi, edx ; esi = start_ptr + offset |
1597 | 1600 | ||
1598 | neg edx |
1601 | neg edx |
1599 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1602 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1600 | jle .no_data_at_all |
1603 | jle .no_data_at_all |
1601 | 1604 | ||
1602 | pusha |
1605 | pusha |
1603 | lea ecx, [eax + RING_BUFFER.mutex] |
1606 | lea ecx, [eax + RING_BUFFER.mutex] |
1604 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1607 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1605 | popa |
1608 | popa |
1606 | 1609 | ||
1607 | cmp ecx, edx |
1610 | cmp ecx, edx |
1608 | ja .less_data |
1611 | ja .less_data |
1609 | 1612 | ||
1610 | .copy: |
1613 | .copy: |
1611 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1614 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1612 | push ecx |
1615 | push ecx |
1613 | shr ecx, 1 |
1616 | shr ecx, 1 |
1614 | jnc .nb |
1617 | jnc .nb |
1615 | movsb |
1618 | movsb |
1616 | .nb: |
1619 | .nb: |
1617 | shr ecx, 1 |
1620 | shr ecx, 1 |
1618 | jnc .nw |
1621 | jnc .nw |
1619 | movsw |
1622 | movsw |
1620 | .nw: |
1623 | .nw: |
1621 | test ecx, ecx |
1624 | test ecx, ecx |
1622 | jz .nd |
1625 | jz .nd |
1623 | rep movsd |
1626 | rep movsd |
1624 | .nd: |
1627 | .nd: |
1625 | pop ecx |
1628 | pop ecx |
1626 | ret |
1629 | ret |
1627 | 1630 | ||
1628 | .no_data_at_all: |
1631 | .no_data_at_all: |
1629 | pusha |
1632 | pusha |
1630 | lea ecx, [eax + RING_BUFFER.mutex] |
1633 | lea ecx, [eax + RING_BUFFER.mutex] |
1631 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1634 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1632 | popa |
1635 | popa |
1633 | 1636 | ||
1634 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: no data at all!\n" |
1637 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: no data at all!\n" |
1635 | xor ecx, ecx |
1638 | xor ecx, ecx |
1636 | ret |
1639 | ret |
1637 | 1640 | ||
1638 | .less_data: |
1641 | .less_data: |
1639 | mov ecx, edx |
1642 | mov ecx, edx |
1640 | jmp .copy |
1643 | jmp .copy |
1641 | 1644 | ||
1642 | 1645 | ||
1643 | ;----------------------------------------------------------------- |
1646 | ;----------------------------------------------------------------- |
1644 | ; |
1647 | ; |
1645 | ; SOCKET_ring_free |
1648 | ; SOCKET_ring_free |
1646 | ; |
1649 | ; |
1647 | ; Free's some bytes from the ringbuffer |
1650 | ; Free's some bytes from the ringbuffer |
1648 | ; |
1651 | ; |
1649 | ; IN: eax = ptr to ring struct |
1652 | ; IN: eax = ptr to ring struct |
1650 | ; ecx = data size |
1653 | ; ecx = data size |
1651 | ; |
1654 | ; |
1652 | ; OUT: ecx = number of bytes free-ed |
1655 | ; OUT: ecx = number of bytes free-ed |
1653 | ; |
1656 | ; |
1654 | ;----------------------------------------------------------------- |
1657 | ;----------------------------------------------------------------- |
1655 | align 4 |
1658 | align 4 |
1656 | SOCKET_ring_free: |
1659 | SOCKET_ring_free: |
1657 | 1660 | ||
1658 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1661 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1659 | 1662 | ||
1660 | push eax ecx |
1663 | push eax ecx |
1661 | lea ecx, [eax + RING_BUFFER.mutex] |
1664 | lea ecx, [eax + RING_BUFFER.mutex] |
1662 | call mutex_lock ; TODO: check what registers this function actually destroys |
1665 | call mutex_lock ; TODO: check what registers this function actually destroys |
1663 | pop ecx eax |
1666 | pop ecx eax |
1664 | 1667 | ||
1665 | sub [eax + RING_BUFFER.size], ecx |
1668 | sub [eax + RING_BUFFER.size], ecx |
1666 | jb .error |
1669 | jb .error |
1667 | add [eax + RING_BUFFER.read_ptr], ecx |
1670 | add [eax + RING_BUFFER.read_ptr], ecx |
1668 | 1671 | ||
1669 | mov edx, [eax + RING_BUFFER.end_ptr] |
1672 | mov edx, [eax + RING_BUFFER.end_ptr] |
1670 | cmp [eax + RING_BUFFER.read_ptr], edx |
1673 | cmp [eax + RING_BUFFER.read_ptr], edx |
1671 | jb @f |
1674 | jb @f |
1672 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1675 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1673 | @@: |
1676 | @@: |
1674 | 1677 | ||
1675 | push eax ecx |
1678 | push eax ecx |
1676 | lea ecx, [eax + RING_BUFFER.mutex] ; TODO: check what registers this function actually destroys |
1679 | lea ecx, [eax + RING_BUFFER.mutex] ; TODO: check what registers this function actually destroys |
1677 | call mutex_unlock |
1680 | call mutex_unlock |
1678 | pop ecx eax |
1681 | pop ecx eax |
1679 | 1682 | ||
1680 | ret |
1683 | ret |
1681 | 1684 | ||
1682 | .error: ; we could free all available bytes, but that would be stupid, i guess.. |
1685 | .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 |
1686 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: buffer=%x error!\n", eax |
1684 | add [eax + RING_BUFFER.size], ecx |
1687 | add [eax + RING_BUFFER.size], ecx |
1685 | 1688 | ||
1686 | push eax |
1689 | push eax |
1687 | lea ecx, [eax + RING_BUFFER.mutex] |
1690 | lea ecx, [eax + RING_BUFFER.mutex] |
1688 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1691 | call mutex_unlock ; TODO: check what registers this function actually destroys |
1689 | pop eax |
1692 | pop eax |
1690 | 1693 | ||
1691 | xor ecx, ecx |
1694 | xor ecx, ecx |
1692 | ret |
1695 | ret |
1693 | 1696 | ||
1694 | 1697 | ||
1695 | ;----------------------------------------------------------------- |
1698 | ;----------------------------------------------------------------- |
1696 | ; |
1699 | ; |
1697 | ; SOCKET_block |
1700 | ; SOCKET_block |
1698 | ; |
1701 | ; |
1699 | ; Suspends the thread attached to a socket |
1702 | ; Suspends the thread attached to a socket |
1700 | ; |
1703 | ; |
1701 | ; IN: eax = socket ptr |
1704 | ; IN: eax = socket ptr |
1702 | ; OUT: eax = unchanged |
1705 | ; OUT: eax = unchanged |
1703 | ; |
1706 | ; |
1704 | ;----------------------------------------------------------------- |
1707 | ;----------------------------------------------------------------- |
1705 | align 4 |
1708 | align 4 |
1706 | SOCKET_block: |
1709 | SOCKET_block: |
1707 | 1710 | ||
1708 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax |
1711 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax |
1709 | - | ||
1710 | pushf |
1712 | |
- | 1713 | push eax |
|
- | 1714 | ||
1711 | push eax |
1715 | pushf |
1712 | cli |
1716 | cli |
1713 | 1717 | ||
1714 | ; Set the 'socket is blocked' flag |
1718 | ; Set the 'socket is blocked' flag |
1715 | or [eax + SOCKET.state], SS_BLOCKED |
1719 | or [eax + SOCKET.state], SS_BLOCKED |
1716 | 1720 | ||
1717 | ; Suspend the thread |
1721 | ; Suspend the thread |
1718 | push edx |
1722 | push edx |
1719 | mov edx, [TASK_BASE] |
1723 | mov edx, [TASK_BASE] |
1720 | mov [edx + TASKDATA.state], 1 ; Suspended |
1724 | mov [edx + TASKDATA.state], 1 ; Suspended |
1721 | 1725 | ||
1722 | ; Remember the thread ID so we can wake it up again |
1726 | ; Remember the thread ID so we can wake it up again |
1723 | mov edx, [edx + TASKDATA.pid] |
1727 | mov edx, [edx + TASKDATA.pid] |
1724 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx |
1728 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx |
1725 | mov [eax + SOCKET.TID], edx |
1729 | mov [eax + SOCKET.TID], edx |
1726 | pop edx |
1730 | pop edx |
- | 1731 | popf |
|
1727 | 1732 | ||
1728 | call change_task |
1733 | call change_task |
1729 | pop eax |
1734 | pop eax |
1730 | popf |
- | |
1731 | 1735 | ||
1732 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n" |
1736 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n" |
1733 | 1737 | ||
1734 | ret |
1738 | ret |
1735 | 1739 | ||
1736 | 1740 | ||
1737 | ;----------------------------------------------------------------- |
1741 | ;----------------------------------------------------------------- |
1738 | ; |
1742 | ; |
1739 | ; SOCKET_notify |
1743 | ; SOCKET_notify |
1740 | ; |
1744 | ; |
1741 | ; notify's the owner of a socket that something happened |
1745 | ; notify's the owner of a socket that something happened |
1742 | ; |
1746 | ; |
1743 | ; IN: eax = socket ptr |
1747 | ; IN: eax = socket ptr |
1744 | ; OUT: eax = unchanged |
1748 | ; OUT: eax = unchanged |
1745 | ; |
1749 | ; |
1746 | ;----------------------------------------------------------------- |
1750 | ;----------------------------------------------------------------- |
1747 | align 4 |
1751 | align 4 |
1748 | SOCKET_notify: |
1752 | SOCKET_notify: |
1749 | 1753 | ||
1750 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: %x\n", eax |
1754 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: %x\n", eax |
1751 | 1755 | ||
1752 | call SOCKET_check |
1756 | call SOCKET_check |
1753 | jz .error |
1757 | 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 |
1758 | |
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: |
1759 | ; 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 |
1760 | push ebx ecx esi |
1795 | mov eax, [eax + SOCKET.TID] |
1761 | mov ebx, [eax + SOCKET.TID] |
1796 | test eax, eax |
1762 | test ebx, ebx |
1797 | jz .error |
1763 | jz .error2 |
1798 | xor ecx, ecx |
1764 | xor ecx, ecx |
1799 | inc ecx |
1765 | inc ecx |
1800 | mov esi, TASK_DATA |
1766 | mov esi, TASK_DATA |
1801 | .next: |
1767 | .next: |
1802 | cmp [esi + TASKDATA.pid], eax |
1768 | cmp [esi + TASKDATA.pid], ebx |
1803 | je .found |
1769 | je .found |
1804 | inc ecx |
1770 | inc ecx |
1805 | add esi, 0x20 |
1771 | add esi, 0x20 |
1806 | cmp ecx, [TASK_COUNT] |
1772 | cmp ecx, [TASK_COUNT] |
1807 | jbe .next |
1773 | jbe .next |
- | 1774 | ||
- | 1775 | .error2: |
|
- | 1776 | ; PID not found, TODO: close socket! |
|
- | 1777 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx |
|
1808 | jmp .error |
1778 | pop esi ecx ebx |
- | 1779 | ret |
|
- | 1780 | ||
- | 1781 | .error: |
|
- | 1782 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: invalid socket ptr: 0x%x !\n", eax |
|
- | 1783 | ret |
|
- | 1784 | ||
1809 | .found: |
1785 | .found: |
- | 1786 | test [eax + SOCKET.state], SS_BLOCKED |
|
- | 1787 | jnz .un_block |
|
- | 1788 | ||
1810 | 1789 | ; socket and thread exists and socket is of non blocking type. |
|
1811 | ; Run the thread |
1790 | ; We'll try to flag an event to the thread. |
1812 | mov [esi + TASKDATA.state], 0 ; Running |
1791 | shl ecx, 8 |
1813 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" |
- | |
- | 1792 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
|
1814 | 1793 | ||
- | 1794 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax |
|
- | 1795 | pop esi ecx ebx |
|
1815 | .done: |
1796 | ret |
- | 1797 | ||
- | 1798 | ||
- | 1799 | .un_block: |
|
- | 1800 | ; socket and thread exists and socket is of blocking type |
|
- | 1801 | ; We'll try to unblock it. |
|
- | 1802 | and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag |
|
- | 1803 | mov [esi + TASKDATA.state], 0 ; Run the thread |
|
1816 | pop esi ecx eax |
1804 | |
1817 | 1805 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" |
|
1818 | .error: |
1806 | pop esi ecx ebx |
1819 | ret |
1807 | ret |
1820 | 1808 | ||
1821 | 1809 | ||
1822 | ;-------------------------------------------------------------------- |
1810 | ;-------------------------------------------------------------------- |
1823 | ; |
1811 | ; |
1824 | ; SOCKET_alloc |
1812 | ; SOCKET_alloc |
1825 | ; |
1813 | ; |
1826 | ; Allocate memory for socket data and put new socket into the list |
1814 | ; Allocate memory for socket data and put new socket into the list |
1827 | ; Newly created socket is initialized with calling PID and number and |
1815 | ; Newly created socket is initialized with calling PID and number and |
1828 | ; put into beginning of list (which is a fastest way). |
1816 | ; put into beginning of list (which is a fastest way). |
1829 | ; |
1817 | ; |
1830 | ; IN: / |
1818 | ; IN: / |
1831 | ; OUT: eax = 0 on error, socket ptr otherwise |
1819 | ; OUT: eax = 0 on error, socket ptr otherwise |
1832 | ; edi = socket number |
1820 | ; edi = socket number |
1833 | ; ZF = cleared on error |
- | |
1834 | ; |
1821 | ; |
1835 | ;-------------------------------------------------------------------- |
1822 | ;-------------------------------------------------------------------- |
1836 | align 4 |
1823 | align 4 |
1837 | SOCKET_alloc: |
1824 | SOCKET_alloc: |
1838 | 1825 | ||
1839 | push ebx |
1826 | push ebx |
1840 | 1827 | ||
1841 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1828 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1842 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax |
1829 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax |
1843 | or eax, eax |
1830 | or eax, eax |
1844 | jz .exit |
1831 | jz .exit |
1845 | 1832 | ||
1846 | ; zero-initialize allocated memory |
1833 | ; zero-initialize allocated memory |
1847 | push eax |
1834 | push eax |
1848 | mov edi, eax |
1835 | mov edi, eax |
1849 | mov ecx, SOCKETBUFFSIZE / 4 |
1836 | mov ecx, SOCKETBUFFSIZE / 4 |
1850 | xor eax, eax |
1837 | xor eax, eax |
1851 | rep stosd |
1838 | rep stosd |
1852 | pop eax |
1839 | pop eax |
1853 | 1840 | ||
1854 | ; set send-and receive procedures to return -1 |
1841 | ; set send-and receive procedures to return -1 |
1855 | mov [eax + SOCKET.snd_proc], .not_yet |
1842 | mov [eax + SOCKET.snd_proc], .not_yet |
1856 | mov [eax + SOCKET.rcv_proc], .not_yet |
1843 | mov [eax + SOCKET.rcv_proc], .not_yet |
1857 | 1844 | ||
1858 | pusha |
1845 | pusha |
1859 | mov ecx, socket_mutex |
1846 | mov ecx, socket_mutex |
1860 | call mutex_lock |
1847 | call mutex_lock |
1861 | popa |
1848 | popa |
1862 | 1849 | ||
1863 | ; find first free socket number and use it |
1850 | ; find first free socket number and use it |
1864 | mov edi, [last_socket_num] |
1851 | mov edi, [last_socket_num] |
1865 | .next_socket_number: |
1852 | .next_socket_number: |
1866 | inc edi |
1853 | inc edi |
1867 | jz .next_socket_number ; avoid socket nr 0 |
1854 | jz .next_socket_number ; avoid socket nr 0 |
1868 | cmp edi, -1 |
1855 | cmp edi, -1 |
1869 | je .next_socket_number ; avoid socket nr -1 |
1856 | je .next_socket_number ; avoid socket nr -1 |
1870 | mov ebx, net_sockets |
1857 | mov ebx, net_sockets |
1871 | .next_socket: |
1858 | .next_socket: |
1872 | mov ebx, [ebx + SOCKET.NextPtr] |
1859 | mov ebx, [ebx + SOCKET.NextPtr] |
1873 | test ebx, ebx |
1860 | test ebx, ebx |
1874 | jz .last_socket |
1861 | jz .last_socket |
1875 | 1862 | ||
1876 | cmp [ebx + SOCKET.Number], edi |
1863 | cmp [ebx + SOCKET.Number], edi |
1877 | jne .next_socket |
1864 | jne .next_socket |
1878 | jmp .next_socket_number |
1865 | jmp .next_socket_number |
1879 | 1866 | ||
1880 | .last_socket: |
1867 | .last_socket: |
1881 | mov [last_socket_num], edi |
1868 | mov [last_socket_num], edi |
1882 | mov [eax + SOCKET.Number], edi |
1869 | mov [eax + SOCKET.Number], edi |
1883 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: number=%u\n", edi |
1870 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: number=%u\n", edi |
1884 | 1871 | ||
1885 | ; Fill in PID |
1872 | ; Fill in PID |
1886 | mov ebx, [TASK_BASE] |
1873 | mov ebx, [TASK_BASE] |
1887 | mov ebx, [ebx + TASKDATA.pid] |
1874 | mov ebx, [ebx + TASKDATA.pid] |
1888 | mov [eax + SOCKET.PID], ebx |
1875 | mov [eax + SOCKET.PID], ebx |
1889 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1876 | mov [eax + SOCKET.TID], ebx ; currently TID = PID in kolibrios :( |
1890 | 1877 | ||
1891 | ; init mutex |
1878 | ; init mutex |
1892 | pusha |
1879 | pusha |
1893 | lea ecx, [eax + SOCKET.mutex] |
1880 | lea ecx, [eax + SOCKET.mutex] |
1894 | call mutex_init |
1881 | call mutex_init |
1895 | popa |
1882 | popa |
1896 | 1883 | ||
1897 | ; add socket to the list by re-arranging some pointers |
1884 | ; add socket to the list by re-arranging some pointers |
1898 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1885 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1899 | 1886 | ||
1900 | mov [eax + SOCKET.PrevPtr], net_sockets |
1887 | mov [eax + SOCKET.PrevPtr], net_sockets |
1901 | mov [eax + SOCKET.NextPtr], ebx |
1888 | mov [eax + SOCKET.NextPtr], ebx |
1902 | 1889 | ||
1903 | test ebx, ebx |
1890 | test ebx, ebx |
1904 | jz @f |
1891 | jz @f |
1905 | 1892 | ||
1906 | pusha |
1893 | pusha |
1907 | lea ecx, [ebx + SOCKET.mutex] |
1894 | lea ecx, [ebx + SOCKET.mutex] |
1908 | call mutex_lock |
1895 | call mutex_lock |
1909 | popa |
1896 | popa |
1910 | 1897 | ||
1911 | mov [ebx + SOCKET.PrevPtr], eax |
1898 | mov [ebx + SOCKET.PrevPtr], eax |
1912 | 1899 | ||
1913 | pusha |
1900 | pusha |
1914 | lea ecx, [ebx + SOCKET.mutex] |
1901 | lea ecx, [ebx + SOCKET.mutex] |
1915 | call mutex_unlock |
1902 | call mutex_unlock |
1916 | popa |
1903 | popa |
1917 | @@: |
1904 | @@: |
1918 | 1905 | ||
1919 | mov [net_sockets + SOCKET.NextPtr], eax |
1906 | mov [net_sockets + SOCKET.NextPtr], eax |
1920 | or eax, eax ; used to clear zero flag |
- | |
1921 | 1907 | ||
1922 | pusha |
1908 | pusha |
1923 | mov ecx, socket_mutex |
1909 | mov ecx, socket_mutex |
1924 | call mutex_unlock |
1910 | call mutex_unlock |
1925 | popa |
1911 | popa |
1926 | 1912 | ||
1927 | .exit: |
1913 | .exit: |
1928 | pop ebx |
1914 | pop ebx |
1929 | 1915 | ||
1930 | ret |
1916 | ret |
1931 | 1917 | ||
1932 | .not_yet: |
1918 | .not_yet: |
1933 | mov dword[esp+20], ENOTCONN |
1919 | mov dword[esp+20], ENOTCONN |
1934 | mov dword[esp+32], -1 |
1920 | mov dword[esp+32], -1 |
1935 | ret |
1921 | ret |
1936 | 1922 | ||
1937 | 1923 | ||
1938 | ;---------------------------------------------------- |
1924 | ;---------------------------------------------------- |
1939 | ; |
1925 | ; |
1940 | ; SOCKET_free |
1926 | ; SOCKET_free |
1941 | ; |
1927 | ; |
1942 | ; Free socket data memory and remove socket from the list |
1928 | ; Free socket data memory and remove socket from the list |
1943 | ; Caller should lock and unlock socket_mutex |
1929 | ; Caller should lock and unlock socket_mutex |
1944 | ; |
1930 | ; |
1945 | ; IN: eax = socket ptr |
1931 | ; IN: eax = socket ptr |
1946 | ; OUT: / |
1932 | ; OUT: / |
1947 | ; |
1933 | ; |
1948 | ;---------------------------------------------------- |
1934 | ;---------------------------------------------------- |
1949 | align 4 |
1935 | align 4 |
1950 | SOCKET_free: |
1936 | SOCKET_free: |
1951 | 1937 | ||
1952 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax |
1938 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax |
1953 | 1939 | ||
1954 | call SOCKET_check |
1940 | call SOCKET_check |
1955 | jz .error |
1941 | jz .error |
1956 | 1942 | ||
1957 | push ebx |
1943 | push ebx |
1958 | 1944 | ||
1959 | pusha |
1945 | pusha |
1960 | lea ecx, [eax + SOCKET.mutex] |
1946 | lea ecx, [eax + SOCKET.mutex] |
1961 | call mutex_lock |
1947 | call mutex_lock |
1962 | popa |
1948 | popa |
1963 | 1949 | ||
1964 | cmp [eax + SOCKET.Domain], AF_INET4 |
1950 | cmp [eax + SOCKET.Domain], AF_INET4 |
1965 | jnz .no_tcp |
1951 | jnz .no_tcp |
1966 | 1952 | ||
1967 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1953 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1968 | jnz .no_tcp |
1954 | jnz .no_tcp |
1969 | 1955 | ||
1970 | mov ebx, eax |
1956 | mov ebx, eax |
1971 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
1957 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
1972 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
1958 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
1973 | mov eax, ebx |
1959 | mov eax, ebx |
1974 | .no_tcp: |
1960 | .no_tcp: |
1975 | 1961 | ||
1976 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax |
1962 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax |
1977 | push eax ; this will be passed to kernel_free |
1963 | push eax ; this will be passed to kernel_free |
1978 | mov ebx, [eax + SOCKET.NextPtr] |
1964 | mov ebx, [eax + SOCKET.NextPtr] |
1979 | mov eax, [eax + SOCKET.PrevPtr] |
1965 | mov eax, [eax + SOCKET.PrevPtr] |
1980 | 1966 | ||
1981 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1967 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1982 | 1968 | ||
1983 | test eax, eax |
1969 | test eax, eax |
1984 | jz @f |
1970 | jz @f |
1985 | mov [eax + SOCKET.NextPtr], ebx |
1971 | mov [eax + SOCKET.NextPtr], ebx |
1986 | @@: |
1972 | @@: |
1987 | 1973 | ||
1988 | test ebx, ebx |
1974 | test ebx, ebx |
1989 | jz @f |
1975 | jz @f |
1990 | mov [ebx + SOCKET.PrevPtr], eax |
1976 | mov [ebx + SOCKET.PrevPtr], eax |
1991 | @@: |
1977 | @@: |
1992 | 1978 | ||
1993 | call kernel_free |
1979 | call kernel_free |
1994 | pop ebx |
1980 | pop ebx |
1995 | 1981 | ||
1996 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n" |
1982 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n" |
1997 | 1983 | ||
1998 | .error: |
1984 | .error: |
1999 | ret |
1985 | ret |
2000 | 1986 | ||
2001 | ;------------------------------------ |
1987 | ;------------------------------------ |
2002 | ; |
1988 | ; |
2003 | ; SOCKET_fork |
1989 | ; SOCKET_fork |
2004 | ; |
1990 | ; |
2005 | ; Create a child socket |
1991 | ; Create a child socket |
2006 | ; |
1992 | ; |
2007 | ; IN: socket nr in ebx |
1993 | ; IN: socket nr in ebx |
2008 | ; OUT: child socket nr in eax |
1994 | ; OUT: child socket nr in eax |
2009 | ; |
1995 | ; |
2010 | ;----------------------------------- |
1996 | ;----------------------------------- |
2011 | align 4 |
1997 | align 4 |
2012 | SOCKET_fork: |
1998 | SOCKET_fork: |
2013 | 1999 | ||
2014 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_fork: %x\n", ebx |
2000 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_fork: %x\n", ebx |
2015 | 2001 | ||
2016 | ; Exit if backlog queue is full |
2002 | ; Exit if backlog queue is full |
2017 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
2003 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
2018 | cmp ax, [ebx + SOCKET.backlog] |
2004 | cmp ax, [ebx + SOCKET.backlog] |
2019 | jae .fail |
2005 | jae .fail |
2020 | 2006 | ||
2021 | ; Allocate new socket |
2007 | ; Allocate new socket |
2022 | push ebx |
2008 | push ebx |
2023 | call SOCKET_alloc |
2009 | call SOCKET_alloc |
2024 | pop ebx |
2010 | pop ebx |
- | 2011 | test eax, eax |
|
2025 | jz .fail |
2012 | jz .fail |
2026 | 2013 | ||
2027 | push eax |
2014 | push eax |
2028 | mov esi, esp |
2015 | mov esi, esp |
2029 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
2016 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
2030 | pop eax |
2017 | pop eax |
2031 | 2018 | ||
2032 | ; Copy structure from current socket to new |
2019 | ; Copy structure from current socket to new |
2033 | ; We start at PID to preserve the socket num, 2 pointers and mutex |
2020 | ; We start at PID to preserve the socket num, 2 pointers and mutex |
2034 | ; TID will be filled in later |
2021 | ; TID will be filled in later |
2035 | lea esi, [ebx + SOCKET.PID] |
2022 | lea esi, [ebx + SOCKET.PID] |
2036 | lea edi, [eax + SOCKET.PID] |
2023 | lea edi, [eax + SOCKET.PID] |
2037 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
2024 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
2038 | rep movsd |
2025 | rep movsd |
2039 | 2026 | ||
2040 | and [eax + SOCKET.options], not SO_ACCEPTCON |
2027 | and [eax + SOCKET.options], not SO_ACCEPTCON |
2041 | 2028 | ||
2042 | ; Notify owner of parent socket |
2029 | ; Notify owner of parent socket |
2043 | push eax |
2030 | push eax |
2044 | mov eax, ebx |
2031 | mov eax, ebx |
2045 | call SOCKET_notify |
2032 | call SOCKET_notify |
2046 | pop eax |
2033 | pop eax |
2047 | 2034 | ||
2048 | ret |
2035 | ret |
2049 | 2036 | ||
2050 | .fail2: |
2037 | .fail2: |
2051 | add esp, 4+4+4 |
2038 | add esp, 4+4+4 |
2052 | .fail: |
2039 | .fail: |
2053 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_fork: failed\n" |
2040 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_fork: failed\n" |
2054 | xor eax, eax |
2041 | xor eax, eax |
2055 | ret |
2042 | ret |
2056 | 2043 | ||
2057 | 2044 | ||
2058 | ;--------------------------------------------------- |
2045 | ;--------------------------------------------------- |
2059 | ; |
2046 | ; |
2060 | ; SOCKET_num_to_ptr |
2047 | ; SOCKET_num_to_ptr |
2061 | ; |
2048 | ; |
2062 | ; Get socket structure address by its number |
2049 | ; Get socket structure address by its number |
2063 | ; |
2050 | ; |
2064 | ; IN: ecx = socket number |
2051 | ; IN: ecx = socket number |
2065 | ; OUT: eax = 0 on error, socket ptr otherwise |
2052 | ; OUT: eax = 0 on error, socket ptr otherwise |
2066 | ; ZF = set on error |
2053 | ; ZF = set on error |
2067 | ; |
2054 | ; |
2068 | ;--------------------------------------------------- |
2055 | ;--------------------------------------------------- |
2069 | align 4 |
2056 | align 4 |
2070 | SOCKET_num_to_ptr: |
2057 | SOCKET_num_to_ptr: |
2071 | 2058 | ||
2072 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx |
2059 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx |
2073 | 2060 | ||
2074 | pusha |
2061 | pusha |
2075 | mov ecx, socket_mutex |
2062 | mov ecx, socket_mutex |
2076 | call mutex_lock |
2063 | call mutex_lock |
2077 | popa |
2064 | popa |
2078 | 2065 | ||
2079 | mov eax, net_sockets |
2066 | mov eax, net_sockets |
2080 | 2067 | ||
2081 | .next_socket: |
2068 | .next_socket: |
2082 | mov eax, [eax + SOCKET.NextPtr] |
2069 | mov eax, [eax + SOCKET.NextPtr] |
2083 | or eax, eax |
2070 | or eax, eax |
2084 | jz .error |
2071 | jz .error |
2085 | cmp [eax + SOCKET.Number], ecx |
2072 | cmp [eax + SOCKET.Number], ecx |
2086 | jne .next_socket |
2073 | jne .next_socket |
2087 | 2074 | ||
2088 | test eax, eax |
2075 | test eax, eax |
2089 | 2076 | ||
2090 | pusha |
2077 | pusha |
2091 | mov ecx, socket_mutex |
2078 | mov ecx, socket_mutex |
2092 | call mutex_unlock |
2079 | call mutex_unlock |
2093 | popa |
2080 | popa |
2094 | 2081 | ||
2095 | DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax |
2082 | DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax |
2096 | ret |
2083 | ret |
2097 | 2084 | ||
2098 | .error: |
2085 | .error: |
2099 | pusha |
2086 | pusha |
2100 | mov ecx, socket_mutex |
2087 | mov ecx, socket_mutex |
2101 | call mutex_unlock |
2088 | call mutex_unlock |
2102 | popa |
2089 | popa |
2103 | 2090 | ||
- | 2091 | 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 |
2092 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: caller = 0x%x\n", [esp] |
2105 | ret |
2093 | ret |
2106 | 2094 | ||
2107 | 2095 | ||
2108 | ;--------------------------------------------------- |
2096 | ;--------------------------------------------------- |
2109 | ; |
2097 | ; |
2110 | ; SOCKET_ptr_to_num |
2098 | ; SOCKET_ptr_to_num |
2111 | ; |
2099 | ; |
2112 | ; Get socket number by its address |
2100 | ; Get socket number by its address |
2113 | ; |
2101 | ; |
2114 | ; IN: eax = socket ptr |
2102 | ; IN: eax = socket ptr |
2115 | ; OUT: eax = 0 on error, socket num otherwise |
2103 | ; OUT: eax = 0 on error, socket num otherwise |
2116 | ; ZF = set on error |
2104 | ; ZF = set on error |
2117 | ; |
2105 | ; |
2118 | ;--------------------------------------------------- |
2106 | ;--------------------------------------------------- |
2119 | align 4 |
2107 | align 4 |
2120 | SOCKET_ptr_to_num: |
2108 | SOCKET_ptr_to_num: |
2121 | 2109 | ||
2122 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ptr_to_num: ptr=%x ", eax |
2110 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ptr_to_num: ptr=%x ", eax |
2123 | 2111 | ||
2124 | call SOCKET_check |
2112 | call SOCKET_check |
2125 | jz .error |
2113 | jz .error |
2126 | 2114 | ||
2127 | mov eax, [eax + SOCKET.Number] |
2115 | mov eax, [eax + SOCKET.Number] |
2128 | 2116 | ||
2129 | DEBUGF DEBUG_NETWORK_VERBOSE, "num=%u\n", eax |
2117 | DEBUGF DEBUG_NETWORK_VERBOSE, "num=%u\n", eax |
2130 | ret |
2118 | ret |
2131 | 2119 | ||
2132 | .error: |
2120 | .error: |
2133 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ptr_to_num: not found\n", eax |
2121 | DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ptr_to_num: not found\n", eax |
2134 | ret |
2122 | ret |
2135 | 2123 | ||
2136 | 2124 | ||
2137 | ;--------------------------------------------------- |
2125 | ;--------------------------------------------------- |
2138 | ; |
2126 | ; |
2139 | ; SOCKET_check |
2127 | ; SOCKET_check |
2140 | ; |
2128 | ; |
2141 | ; checks if the given value is really a socket ptr |
2129 | ; checks if the given value is really a socket ptr |
2142 | ; |
2130 | ; |
2143 | ; IN: eax = socket ptr |
2131 | ; IN: eax = socket ptr |
2144 | ; OUT: eax = 0 on error, unchanged otherwise |
2132 | ; OUT: eax = 0 on error, unchanged otherwise |
2145 | ; ZF = set on error |
2133 | ; ZF = set on error |
2146 | ; |
2134 | ; |
2147 | ;--------------------------------------------------- |
2135 | ;--------------------------------------------------- |
2148 | align 4 |
2136 | align 4 |
2149 | SOCKET_check: |
2137 | SOCKET_check: |
2150 | 2138 | ||
2151 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax |
2139 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax |
2152 | 2140 | ||
2153 | push ebx |
2141 | push ebx |
2154 | mov ebx, net_sockets |
2142 | mov ebx, net_sockets |
2155 | 2143 | ||
2156 | .next_socket: |
2144 | .next_socket: |
2157 | mov ebx, [ebx + SOCKET.NextPtr] |
2145 | mov ebx, [ebx + SOCKET.NextPtr] |
2158 | or ebx, ebx |
2146 | or ebx, ebx |
2159 | jz .done |
2147 | jz .done |
2160 | cmp ebx, eax |
2148 | cmp ebx, eax |
2161 | jnz .next_socket |
2149 | jnz .next_socket |
2162 | 2150 | ||
2163 | .done: |
2151 | .done: |
2164 | mov eax, ebx |
2152 | mov eax, ebx |
2165 | test eax, eax |
2153 | test eax, eax |
2166 | pop ebx |
2154 | pop ebx |
2167 | 2155 | ||
2168 | ret |
2156 | ret |
2169 | 2157 | ||
2170 | 2158 | ||
2171 | 2159 | ||
2172 | ;--------------------------------------------------- |
2160 | ;--------------------------------------------------- |
2173 | ; |
2161 | ; |
2174 | ; SOCKET_check_owner |
2162 | ; SOCKET_check_owner |
2175 | ; |
2163 | ; |
2176 | ; checks if the caller application owns the socket |
2164 | ; checks if the caller application owns the socket |
2177 | ; |
2165 | ; |
2178 | ; IN: eax = socket ptr |
2166 | ; IN: eax = socket ptr |
2179 | ; OUT: ZF = true/false |
2167 | ; OUT: ZF = true/false |
2180 | ; |
2168 | ; |
2181 | ;--------------------------------------------------- |
2169 | ;--------------------------------------------------- |
2182 | align 4 |
2170 | align 4 |
2183 | SOCKET_check_owner: |
2171 | SOCKET_check_owner: |
2184 | 2172 | ||
2185 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_owner: %x\n", eax |
2173 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_owner: %x\n", eax |
2186 | 2174 | ||
2187 | push ebx |
2175 | push ebx |
2188 | mov ebx, [TASK_BASE] |
2176 | mov ebx, [TASK_BASE] |
2189 | mov ebx, [ebx + TASKDATA.pid] |
2177 | mov ebx, [ebx + TASKDATA.pid] |
2190 | cmp [eax + SOCKET.PID], ebx |
2178 | cmp [eax + SOCKET.PID], ebx |
2191 | pop ebx |
2179 | pop ebx |
2192 | 2180 | ||
2193 | ret |
2181 | ret |
2194 | 2182 | ||
2195 | 2183 | ||
2196 | 2184 | ||
2197 | 2185 | ||
2198 | ;------------------------------------------------------ |
2186 | ;------------------------------------------------------ |
2199 | ; |
2187 | ; |
2200 | ; SOCKET_process_end |
2188 | ; SOCKET_process_end |
2201 | ; |
2189 | ; |
2202 | ; Kernel calls this function when a certain process ends |
2190 | ; Kernel calls this function when a certain process ends |
2203 | ; This function will check if the process had any open sockets |
2191 | ; This function will check if the process had any open sockets |
2204 | ; And update them accordingly (clean up) |
2192 | ; And update them accordingly (clean up) |
2205 | ; |
2193 | ; |
2206 | ; IN: edx = pid |
2194 | ; IN: edx = pid |
2207 | ; OUT: / |
2195 | ; OUT: / |
2208 | ; |
2196 | ; |
2209 | ;------------------------------------------------------ |
2197 | ;------------------------------------------------------ |
2210 | align 4 |
2198 | align 4 |
2211 | SOCKET_process_end: |
2199 | SOCKET_process_end: |
2212 | 2200 | ||
2213 | ret ; FIXME |
2201 | ret ; FIXME |
2214 | 2202 | ||
2215 | cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all? |
2203 | cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all? |
2216 | je .quickret ; nope, exit immediately |
2204 | je .quickret ; nope, exit immediately |
2217 | 2205 | ||
2218 | ; TODO: run the following code in another thread, to avoid deadlock |
2206 | ; TODO: run the following code in another thread, to avoid deadlock |
2219 | 2207 | ||
2220 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx |
2208 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx |
2221 | 2209 | ||
2222 | pusha |
2210 | pusha |
2223 | mov ecx, socket_mutex |
2211 | mov ecx, socket_mutex |
2224 | call mutex_lock |
2212 | call mutex_lock |
2225 | popa |
2213 | popa |
2226 | 2214 | ||
2227 | push ebx |
2215 | push ebx |
2228 | mov ebx, net_sockets |
2216 | mov ebx, net_sockets |
2229 | 2217 | ||
2230 | .next_socket: |
2218 | .next_socket: |
2231 | mov ebx, [ebx + SOCKET.NextPtr] |
2219 | mov ebx, [ebx + SOCKET.NextPtr] |
2232 | .next_socket_test: |
2220 | .next_socket_test: |
2233 | test ebx, ebx |
2221 | test ebx, ebx |
2234 | jz .done |
2222 | jz .done |
2235 | 2223 | ||
2236 | cmp [ebx + SOCKET.PID], edx |
2224 | cmp [ebx + SOCKET.PID], edx |
2237 | jne .next_socket |
2225 | jne .next_socket |
2238 | 2226 | ||
2239 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx |
2227 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx |
2240 | 2228 | ||
2241 | mov [ebx + SOCKET.PID], 0 |
2229 | mov [ebx + SOCKET.PID], 0 |
2242 | mov eax, ebx |
2230 | mov eax, ebx |
2243 | mov ebx, [ebx + SOCKET.NextPtr] |
2231 | mov ebx, [ebx + SOCKET.NextPtr] |
2244 | 2232 | ||
2245 | pusha |
2233 | pusha |
2246 | cmp [eax + SOCKET.Domain], AF_INET4 |
2234 | cmp [eax + SOCKET.Domain], AF_INET4 |
2247 | jne .free |
2235 | jne .free |
2248 | 2236 | ||
2249 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
2237 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
2250 | jne .free |
2238 | jne .free |
2251 | 2239 | ||
2252 | call TCP_disconnect |
2240 | call TCP_disconnect |
2253 | jmp .closed |
2241 | jmp .closed |
2254 | 2242 | ||
2255 | .free: |
2243 | .free: |
2256 | call SOCKET_free |
2244 | call SOCKET_free |
2257 | 2245 | ||
2258 | .closed: |
2246 | .closed: |
2259 | popa |
2247 | popa |
2260 | jmp .next_socket_test |
2248 | jmp .next_socket_test |
2261 | 2249 | ||
2262 | .done: |
2250 | .done: |
2263 | pop ebx |
2251 | pop ebx |
2264 | 2252 | ||
2265 | pusha |
2253 | pusha |
2266 | mov ecx, socket_mutex |
2254 | mov ecx, socket_mutex |
2267 | call mutex_unlock |
2255 | call mutex_unlock |
2268 | popa |
2256 | popa |
2269 | 2257 | ||
2270 | .quickret: |
2258 | .quickret: |
2271 | ret |
2259 | ret |
2272 | 2260 | ||
2273 | 2261 | ||
2274 | 2262 | ||
2275 | 2263 | ||
2276 | ;----------------------------------------------------------------- |
2264 | ;----------------------------------------------------------------- |
2277 | ; |
2265 | ; |
2278 | ; SOCKET_is_connecting |
2266 | ; SOCKET_is_connecting |
2279 | ; |
2267 | ; |
2280 | ; IN: eax = socket ptr |
2268 | ; IN: eax = socket ptr |
2281 | ; OUT: / |
2269 | ; OUT: / |
2282 | ; |
2270 | ; |
2283 | ;----------------------------------------------------------------- |
2271 | ;----------------------------------------------------------------- |
2284 | 2272 | ||
2285 | align 4 |
2273 | align 4 |
2286 | SOCKET_is_connecting: |
2274 | SOCKET_is_connecting: |
2287 | 2275 | ||
2288 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax |
2276 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax |
2289 | 2277 | ||
2290 | and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2278 | and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2291 | or [eax + SOCKET.state], SS_ISCONNECTING |
2279 | or [eax + SOCKET.state], SS_ISCONNECTING |
2292 | 2280 | ||
2293 | ret |
2281 | ret |
2294 | 2282 | ||
2295 | 2283 | ||
2296 | 2284 | ||
2297 | ;----------------------------------------------------------------- |
2285 | ;----------------------------------------------------------------- |
2298 | ; |
2286 | ; |
2299 | ; SOCKET_is_connected |
2287 | ; SOCKET_is_connected |
2300 | ; |
2288 | ; |
2301 | ; IN: eax = socket ptr |
2289 | ; IN: eax = socket ptr |
2302 | ; OUT: / |
2290 | ; OUT: / |
2303 | ; |
2291 | ; |
2304 | ;----------------------------------------------------------------- |
2292 | ;----------------------------------------------------------------- |
2305 | 2293 | ||
2306 | align 4 |
2294 | align 4 |
2307 | SOCKET_is_connected: |
2295 | SOCKET_is_connected: |
2308 | 2296 | ||
2309 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax |
2297 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax |
2310 | 2298 | ||
2311 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2299 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
2312 | or [eax + SOCKET.state], SS_ISCONNECTED |
2300 | or [eax + SOCKET.state], SS_ISCONNECTED |
2313 | 2301 | ||
2314 | jmp SOCKET_notify |
2302 | jmp SOCKET_notify |
2315 | 2303 | ||
2316 | 2304 | ||
2317 | 2305 | ||
2318 | 2306 | ||
2319 | ;----------------------------------------------------------------- |
2307 | ;----------------------------------------------------------------- |
2320 | ; |
2308 | ; |
2321 | ; SOCKET_is_disconnecting |
2309 | ; SOCKET_is_disconnecting |
2322 | ; |
2310 | ; |
2323 | ; IN: eax = socket ptr |
2311 | ; IN: eax = socket ptr |
2324 | ; OUT: / |
2312 | ; OUT: / |
2325 | ; |
2313 | ; |
2326 | ;----------------------------------------------------------------- |
2314 | ;----------------------------------------------------------------- |
2327 | 2315 | ||
2328 | align 4 |
2316 | align 4 |
2329 | SOCKET_is_disconnecting: |
2317 | SOCKET_is_disconnecting: |
2330 | 2318 | ||
2331 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax |
2319 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax |
2332 | 2320 | ||
2333 | and [eax + SOCKET.state], not (SS_ISCONNECTING) |
2321 | and [eax + SOCKET.state], not (SS_ISCONNECTING) |
2334 | or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
2322 | or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
2335 | 2323 | ||
2336 | jmp SOCKET_notify |
2324 | jmp SOCKET_notify |
2337 | 2325 | ||
2338 | 2326 | ||
2339 | 2327 | ||
2340 | ;----------------------------------------------------------------- |
2328 | ;----------------------------------------------------------------- |
2341 | ; |
2329 | ; |
2342 | ; SOCKET_is_disconnected |
2330 | ; SOCKET_is_disconnected |
2343 | ; |
2331 | ; |
2344 | ; IN: eax = socket ptr |
2332 | ; IN: eax = socket ptr |
2345 | ; OUT: / |
2333 | ; OUT: / |
2346 | ; |
2334 | ; |
2347 | ;----------------------------------------------------------------- |
2335 | ;----------------------------------------------------------------- |
2348 | 2336 | ||
2349 | align 4 |
2337 | align 4 |
2350 | SOCKET_is_disconnected: |
2338 | SOCKET_is_disconnected: |
2351 | 2339 | ||
2352 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax |
2340 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax |
2353 | 2341 | ||
2354 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
2342 | and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
2355 | or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE |
2343 | or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE |
2356 | 2344 | ||
2357 | 2345 | ||
2358 | jmp SOCKET_notify |
2346 | jmp SOCKET_notify |
2359 | 2347 | ||
2360 | 2348 | ||
2361 | 2349 | ||
2362 | ;----------------------------------------------------------------- |
2350 | ;----------------------------------------------------------------- |
2363 | ; |
2351 | ; |
2364 | ; SOCKET_cant_recv_more |
2352 | ; SOCKET_cant_recv_more |
2365 | ; |
2353 | ; |
2366 | ; IN: eax = socket ptr |
2354 | ; IN: eax = socket ptr |
2367 | ; OUT: / |
2355 | ; OUT: / |
2368 | ; |
2356 | ; |
2369 | ;----------------------------------------------------------------- |
2357 | ;----------------------------------------------------------------- |
2370 | 2358 | ||
2371 | align 4 |
2359 | align 4 |
2372 | SOCKET_cant_recv_more: |
2360 | SOCKET_cant_recv_more: |
2373 | 2361 | ||
2374 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax |
2362 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax |
2375 | 2363 | ||
2376 | or [eax + SOCKET.state], SS_CANTRCVMORE |
2364 | or [eax + SOCKET.state], SS_CANTRCVMORE |
2377 | 2365 | ||
2378 | call SOCKET_notify |
2366 | call SOCKET_notify |
2379 | 2367 | ||
2380 | ret |
2368 | ret |
2381 | 2369 | ||
2382 | 2370 | ||
2383 | 2371 | ||
2384 | ;----------------------------------------------------------------- |
2372 | ;----------------------------------------------------------------- |
2385 | ; |
2373 | ; |
2386 | ; SOCKET_cant_send_more |
2374 | ; SOCKET_cant_send_more |
2387 | ; |
2375 | ; |
2388 | ; IN: eax = socket ptr |
2376 | ; IN: eax = socket ptr |
2389 | ; OUT: / |
2377 | ; OUT: / |
2390 | ; |
2378 | ; |
2391 | ;----------------------------------------------------------------- |
2379 | ;----------------------------------------------------------------- |
2392 | 2380 | ||
2393 | align 4 |
2381 | align 4 |
2394 | SOCKET_cant_send_more: |
2382 | SOCKET_cant_send_more: |
2395 | 2383 | ||
2396 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax |
2384 | DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax |
2397 | 2385 | ||
2398 | or [eax + SOCKET.state], SS_CANTSENDMORE |
2386 | or [eax + SOCKET.state], SS_CANTSENDMORE |
2399 | mov [eax + SOCKET.snd_proc], .notconn |
2387 | mov [eax + SOCKET.snd_proc], .notconn |
2400 | 2388 | ||
2401 | call SOCKET_notify |
2389 | call SOCKET_notify |
2402 | 2390 | ||
2403 | ret |
2391 | ret |
2404 | 2392 | ||
2405 | .notconn: |
2393 | .notconn: |
2406 | mov dword[esp+20], ENOTCONN |
2394 | mov dword[esp+20], ENOTCONN |
2407 | mov dword[esp+32], -1 |
2395 | mov dword[esp+32], -1 |
2408 | ret |
2396 | ret |