2 * Server-side socket management
4 * Copyright (C) 1999 Marcus Meissner, Ove Kåven
6 * FIXME: we use read|write access in all cases. Shouldn't we depend that
7 * on the access of the current handle?
18 #ifdef HAVE_SYS_ERRNO_H
19 # include <sys/errno.h>
23 #include <sys/types.h>
24 #ifdef HAVE_SYS_SOCKET_H
25 # include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #ifdef HAVE_SYS_FILIO_H
29 # include <sys/filio.h>
44 struct object obj
; /* object header */
45 struct select_user select
; /* select user */
46 unsigned int state
; /* status bits */
47 unsigned int mask
; /* event mask */
48 unsigned int hmask
; /* held (blocked) events */
49 unsigned int pmask
; /* pending events */
50 struct event
*event
; /* event object */
51 int errors
[FD_MAX_EVENTS
]; /* event errors */
54 static void sock_dump( struct object
*obj
, int verbose
);
55 static int sock_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
56 static void sock_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
57 static int sock_signaled( struct object
*obj
, struct thread
*thread
);
58 static int sock_get_fd( struct object
*obj
);
59 static void sock_destroy( struct object
*obj
);
60 static void sock_set_error(void);
62 static const struct object_ops sock_ops
=
77 static int sock_event( struct sock
*sock
)
79 unsigned int mask
= sock
->mask
& sock
->state
& ~sock
->hmask
;
80 int ev
= EXCEPT_EVENT
;
82 if (sock
->state
& WS_FD_CONNECT
)
83 /* connecting, wait for writable */
84 return WRITE_EVENT
| EXCEPT_EVENT
;
85 if (sock
->state
& WS_FD_LISTENING
)
86 /* listening, wait for readable */
87 return ((sock
->hmask
& FD_ACCEPT
) ? 0 : READ_EVENT
) | EXCEPT_EVENT
;
89 if (mask
& FD_READ
) ev
|= READ_EVENT
;
90 if (mask
& FD_WRITE
) ev
|= WRITE_EVENT
;
94 static void sock_reselect( struct sock
*sock
)
96 int ev
= sock_event( sock
);
98 fprintf(stderr
,"sock_reselect(%d): new mask %x\n", sock
->select
.fd
, ev
);
99 set_select_events( &sock
->select
, ev
);
102 inline static int sock_error(int s
)
104 unsigned int optval
, optlen
;
106 optlen
= sizeof(optval
);
107 getsockopt(s
, SOL_SOCKET
, SO_ERROR
, (void *) &optval
, &optlen
);
111 static void sock_select_event( int event
, void *private )
113 struct sock
*sock
= (struct sock
*)private;
115 assert( sock
->obj
.ops
== &sock_ops
);
117 fprintf(stderr
, "socket %d select event: %x\n", sock
->select
.fd
, event
);
118 if (sock
->state
& WS_FD_CONNECT
)
121 if (event
& WRITE_EVENT
)
123 /* we got connected */
124 sock
->state
|= WS_FD_CONNECTED
|WS_FD_READ
|WS_FD_WRITE
;
125 sock
->state
&= ~WS_FD_CONNECT
;
126 sock
->pmask
|= FD_CONNECT
;
127 sock
->errors
[FD_CONNECT_BIT
] = 0;
129 fprintf(stderr
, "socket %d connection success\n", sock
->select
.fd
);
131 else if (event
& EXCEPT_EVENT
)
133 /* we didn't get connected? */
134 sock
->state
&= ~WS_FD_CONNECT
;
135 sock
->pmask
|= FD_CONNECT
;
136 sock
->errors
[FD_CONNECT_BIT
] = sock_error( sock
->select
.fd
);
138 fprintf(stderr
, "socket %d connection failure\n", sock
->select
.fd
);
141 if (sock
->state
& WS_FD_LISTENING
)
144 if (event
& READ_EVENT
)
146 /* incoming connection */
147 sock
->pmask
|= FD_ACCEPT
;
148 sock
->errors
[FD_ACCEPT_BIT
] = 0;
149 sock
->hmask
|= FD_ACCEPT
;
151 else if (event
& EXCEPT_EVENT
)
153 /* failed incoming connection? */
154 sock
->pmask
|= FD_ACCEPT
;
155 sock
->errors
[FD_ACCEPT_BIT
] = sock_error( sock
->select
.fd
);
156 sock
->hmask
|= FD_ACCEPT
;
160 /* normal data flow */
161 if (event
& READ_EVENT
)
163 /* make sure there's data here */
165 ioctl(sock
->select
.fd
, FIONREAD
, (char*)&bytes
);
169 sock
->pmask
|= FD_READ
;
170 sock
->hmask
|= FD_READ
;
171 sock
->errors
[FD_READ_BIT
] = 0;
173 fprintf(stderr
, "socket %d has %d bytes\n", sock
->select
.fd
, bytes
);
177 /* 0 bytes readable == socket closed cleanly */
178 sock
->state
&= ~(WS_FD_CONNECTED
|WS_FD_READ
|WS_FD_WRITE
);
179 sock
->pmask
|= FD_CLOSE
;
180 sock
->errors
[FD_CLOSE_BIT
] = 0;
182 fprintf(stderr
, "socket %d is closing\n", sock
->select
.fd
);
185 if (event
& WRITE_EVENT
)
187 sock
->pmask
|= FD_WRITE
;
188 sock
->hmask
|= FD_WRITE
;
189 sock
->errors
[FD_WRITE_BIT
] = 0;
191 fprintf(stderr
, "socket %d is writable\n", sock
->select
.fd
);
193 if (event
& EXCEPT_EVENT
)
195 sock
->errors
[FD_CLOSE_BIT
] = sock_error( sock
->select
.fd
);
196 if (sock
->errors
[FD_CLOSE_BIT
])
198 /* we got an error, socket closing? */
199 sock
->state
&= ~(WS_FD_CONNECTED
|WS_FD_READ
|WS_FD_WRITE
);
200 sock
->pmask
|= FD_CLOSE
;
202 fprintf(stderr
, "socket %d aborted by error %d\n", sock
->select
.fd
, sock
->errors
[FD_CLOSE_BIT
]);
206 /* no error, OOB data? */
207 sock
->pmask
|= FD_OOB
;
208 sock
->hmask
|= FD_OOB
;
210 fprintf(stderr
, "socket %d got OOB data\n", sock
->select
.fd
);
215 sock_reselect( sock
);
216 /* wake up anyone waiting for whatever just happened */
217 emask
= sock
->pmask
& sock
->mask
;
218 if (debug_level
&& emask
)
219 fprintf(stderr
, "socket %d pending events: %x\n", sock
->select
.fd
, emask
);
220 if (emask
&& sock
->event
) {
221 if (debug_level
) fprintf(stderr
, "signalling event ptr %p\n", sock
->event
);
222 set_event(sock
->event
);
225 /* if anyone is stupid enough to wait on the socket object itself,
226 * maybe we should wake them up too, just in case? */
227 wake_up( &sock
->obj
, 0 );
230 static void sock_dump( struct object
*obj
, int verbose
)
232 struct sock
*sock
= (struct sock
*)obj
;
233 assert( obj
->ops
== &sock_ops
);
234 printf( "Socket fd=%d, state=%x, mask=%x, pending=%x, held=%x\n",
235 sock
->select
.fd
, sock
->state
,
236 sock
->mask
, sock
->pmask
, sock
->hmask
);
239 static int sock_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
241 /* struct sock *sock = (struct sock *)obj; */
242 assert( obj
->ops
== &sock_ops
);
244 add_queue( obj
, entry
);
248 static void sock_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
250 /* struct sock *sock = (struct sock *)grab_object(obj); */
251 assert( obj
->ops
== &sock_ops
);
253 remove_queue( obj
, entry
);
254 /* release_object( obj ); */
257 static int sock_signaled( struct object
*obj
, struct thread
*thread
)
259 struct sock
*sock
= (struct sock
*)obj
;
260 assert( obj
->ops
== &sock_ops
);
262 return check_select_events( &sock
->select
, sock_event( sock
) );
265 static int sock_get_fd( struct object
*obj
)
267 struct sock
*sock
= (struct sock
*)obj
;
269 assert( obj
->ops
== &sock_ops
);
270 fd
= dup( sock
->select
.fd
);
276 static void sock_destroy( struct object
*obj
)
278 struct sock
*sock
= (struct sock
*)obj
;
279 assert( obj
->ops
== &sock_ops
);
281 unregister_select_user( &sock
->select
);
282 /* FIXME: special socket shutdown stuff? */
283 close( sock
->select
.fd
);
286 /* if the service thread was waiting for the event object,
287 * we should now signal it, to let the service thread
288 * object detect that it is now orphaned... */
289 if (sock
->mask
& WS_FD_SERVEVENT
)
290 set_event( sock
->event
);
291 /* we're through with it */
292 release_object( sock
->event
);
296 /* create a new and unconnected socket */
297 static struct object
*create_socket( int family
, int type
, int protocol
)
301 if (!(sock
= alloc_object( &sock_ops
)))
303 sock
->select
.fd
= socket(family
,type
,protocol
);
304 sock
->select
.func
= sock_select_event
;
305 sock
->select
.private = sock
;
306 sock
->state
= (type
!=SOCK_STREAM
) ? WS_FD_READ
|WS_FD_WRITE
: 0;
312 fprintf(stderr
,"socket(%d,%d,%d)=%d\n",family
,type
,protocol
,sock
->select
.fd
);
313 fcntl(sock
->select
.fd
, F_SETFL
, O_NONBLOCK
); /* make socket nonblocking */
314 register_select_user( &sock
->select
);
315 sock_reselect( sock
);
320 /* accept a socket (creates a new fd) */
321 static struct object
*accept_socket( int handle
)
323 struct sock
*acceptsock
;
326 struct sockaddr saddr
;
329 sock
=(struct sock
*)get_handle_obj(current
->process
,handle
,
330 GENERIC_READ
|GENERIC_WRITE
|SYNCHRONIZE
,&sock_ops
);
333 /* Try to accept(2). We can't be safe that this an already connected socket
334 * or that accept() is allowed on it. In those cases we will get -1/errno
337 slen
= sizeof(saddr
);
338 acceptfd
= accept(sock
->select
.fd
,&saddr
,&slen
);
341 release_object( sock
);
344 if (!(acceptsock
= alloc_object( &sock_ops
)))
346 release_object( sock
);
350 acceptsock
->select
.fd
= acceptfd
;
351 acceptsock
->select
.func
= sock_select_event
;
352 acceptsock
->select
.private = acceptsock
;
353 acceptsock
->state
= WS_FD_CONNECTED
|WS_FD_READ
|WS_FD_WRITE
;
354 acceptsock
->mask
= sock
->mask
;
355 acceptsock
->hmask
= 0;
356 acceptsock
->pmask
= 0;
357 acceptsock
->event
= (struct event
*)grab_object( sock
->event
);
358 register_select_user( &acceptsock
->select
);
359 sock_reselect( acceptsock
);
361 sock
->pmask
&= ~FD_ACCEPT
;
362 sock
->hmask
&= ~FD_ACCEPT
;
363 release_object( sock
);
364 return &acceptsock
->obj
;
367 /* set the last error depending on errno */
368 static void sock_set_error(void)
372 case EINTR
: set_error(WSAEINTR
);break;
373 case EBADF
: set_error(WSAEBADF
);break;
375 case EACCES
: set_error(WSAEACCES
);break;
376 case EFAULT
: set_error(WSAEFAULT
);break;
377 case EINVAL
: set_error(WSAEINVAL
);break;
378 case EMFILE
: set_error(WSAEMFILE
);break;
379 case EWOULDBLOCK
: set_error(WSAEWOULDBLOCK
);break;
380 case EINPROGRESS
: set_error(WSAEINPROGRESS
);break;
381 case EALREADY
: set_error(WSAEALREADY
);break;
382 case ENOTSOCK
: set_error(WSAENOTSOCK
);break;
383 case EDESTADDRREQ
: set_error(WSAEDESTADDRREQ
);break;
384 case EMSGSIZE
: set_error(WSAEMSGSIZE
);break;
385 case EPROTOTYPE
: set_error(WSAEPROTOTYPE
);break;
386 case ENOPROTOOPT
: set_error(WSAENOPROTOOPT
);break;
387 case EPROTONOSUPPORT
: set_error(WSAEPROTONOSUPPORT
);break;
388 case ESOCKTNOSUPPORT
: set_error(WSAESOCKTNOSUPPORT
);break;
389 case EOPNOTSUPP
: set_error(WSAEOPNOTSUPP
);break;
390 case EPFNOSUPPORT
: set_error(WSAEPFNOSUPPORT
);break;
391 case EAFNOSUPPORT
: set_error(WSAEAFNOSUPPORT
);break;
392 case EADDRINUSE
: set_error(WSAEADDRINUSE
);break;
393 case EADDRNOTAVAIL
: set_error(WSAEADDRNOTAVAIL
);break;
394 case ENETDOWN
: set_error(WSAENETDOWN
);break;
395 case ENETUNREACH
: set_error(WSAENETUNREACH
);break;
396 case ENETRESET
: set_error(WSAENETRESET
);break;
397 case ECONNABORTED
: set_error(WSAECONNABORTED
);break;
399 case ECONNRESET
: set_error(WSAECONNRESET
);break;
400 case ENOBUFS
: set_error(WSAENOBUFS
);break;
401 case EISCONN
: set_error(WSAEISCONN
);break;
402 case ENOTCONN
: set_error(WSAENOTCONN
);break;
403 case ESHUTDOWN
: set_error(WSAESHUTDOWN
);break;
404 case ETOOMANYREFS
: set_error(WSAETOOMANYREFS
);break;
405 case ETIMEDOUT
: set_error(WSAETIMEDOUT
);break;
406 case ECONNREFUSED
: set_error(WSAECONNREFUSED
);break;
407 case ELOOP
: set_error(WSAELOOP
);break;
408 case ENAMETOOLONG
: set_error(WSAENAMETOOLONG
);break;
409 case EHOSTDOWN
: set_error(WSAEHOSTDOWN
);break;
410 case EHOSTUNREACH
: set_error(WSAEHOSTUNREACH
);break;
411 case ENOTEMPTY
: set_error(WSAENOTEMPTY
);break;
413 case EPROCLIM
: set_error(WSAEPROCLIM
);break;
416 case EUSERS
: set_error(WSAEUSERS
);break;
419 case EDQUOT
: set_error(WSAEDQUOT
);break;
422 case ESTALE
: set_error(WSAESTALE
);break;
425 case EREMOTE
: set_error(WSAEREMOTE
);break;
427 default: perror("sock_set_error"); set_error( ERROR_UNKNOWN
); break;
431 /* create a socket */
432 DECL_HANDLER(create_socket
)
437 if ((obj
= create_socket( req
->family
, req
->type
, req
->protocol
)) != NULL
)
439 s
= alloc_handle( current
->process
, obj
, req
->access
, req
->inherit
);
440 release_object( obj
);
445 /* accept a socket */
446 DECL_HANDLER(accept_socket
)
451 if ((obj
= accept_socket( req
->lhandle
)) != NULL
)
453 s
= alloc_handle( current
->process
, obj
, req
->access
, req
->inherit
);
454 release_object( obj
);
459 /* set socket event parameters */
460 DECL_HANDLER(set_socket_event
)
463 struct event
*oevent
;
466 sock
=(struct sock
*)get_handle_obj(current
->process
,req
->handle
,GENERIC_READ
|GENERIC_WRITE
|SYNCHRONIZE
,&sock_ops
);
469 oevent
= sock
->event
;
471 sock
->mask
= req
->mask
;
472 sock
->event
= get_event_obj( current
->process
, req
->event
, EVENT_MODIFY_STATE
);
473 if (debug_level
&& sock
->event
) fprintf(stderr
, "event ptr: %p\n", sock
->event
);
474 sock_reselect( sock
);
476 sock
->state
|= WS_FD_NONBLOCKING
;
479 if ((oevent
!= sock
->event
) && (omask
& WS_FD_SERVEVENT
))
480 /* if the service thread was waiting for the old event object,
481 * we should now signal it, to let the service thread
482 * object detect that it is now orphaned... */
484 /* we're through with it */
485 release_object( oevent
);
487 release_object( &sock
->obj
);
490 /* get socket event parameters */
491 DECL_HANDLER(get_socket_event
)
495 sock
=(struct sock
*)get_handle_obj(current
->process
,req
->handle
,GENERIC_READ
|GENERIC_WRITE
|SYNCHRONIZE
,&sock_ops
);
501 set_error(WSAENOTSOCK
);
504 req
->mask
= sock
->mask
;
505 req
->pmask
= sock
->pmask
;
506 req
->state
= sock
->state
;
507 memcpy(req
->errors
, sock
->errors
, sizeof(sock
->errors
));
513 struct event
*sevent
= get_event_obj(current
->process
, req
->s_event
, 0);
514 if (sevent
== sock
->event
)
516 release_object( sevent
);
521 sock_reselect( sock
);
523 else set_error(WSAEINVAL
);
525 release_object( &sock
->obj
);
528 /* re-enable pending socket events */
529 DECL_HANDLER(enable_socket_event
)
533 sock
=(struct sock
*)get_handle_obj(current
->process
,req
->handle
,GENERIC_READ
|GENERIC_WRITE
|SYNCHRONIZE
,&sock_ops
);
536 sock
->pmask
&= ~req
->mask
; /* is this safe? */
537 sock
->hmask
&= ~req
->mask
;
538 sock
->state
|= req
->sstate
;
539 sock
->state
&= ~req
->cstate
;
540 sock_reselect( sock
);
541 release_object( &sock
->obj
);