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