r4728: split up server_services into:
authorStefan Metzmacher <metze@samba.org>
Fri, 14 Jan 2005 01:32:56 +0000 (01:32 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:49 +0000 (13:08 -0500)
- stream_socket services
  the smb, ldap and rpc service which sets up a srtam socket end then
  waits for connections
and
- task services
  which this you can create a seperate task that do something
  (this is also going through the process_model subsystem
  so with -M standard a new process for this created
  with -M thread a new thread ...

I'll add datagram services later when we whave support for datagram sockets in lib/socket/

see the next commit as an example for service_task's

metze
(This used to be commit d5fa02746c6569b09b6e05785642da2fad3ba3e0)

21 files changed:
source4/ldap_server/ldap_server.c
source4/ntvfs/posix/pvfs_wait.c
source4/ntvfs/posix/vfs_posix.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_sock.c
source4/smb_server/negprot.c
source4/smb_server/request.c
source4/smb_server/service.c
source4/smb_server/smb_server.c
source4/smb_server/smb_server.h
source4/smbd/config.mk
source4/smbd/process_model.c
source4/smbd/process_model.h
source4/smbd/process_single.c
source4/smbd/process_standard.c
source4/smbd/process_thread.c
source4/smbd/rewrite.c
source4/smbd/server.c
source4/smbd/server.h
source4/smbd/service.c
source4/smbd/service.h

index bc851713b5987036d040f872ca53112deaa9fbc5..52a519721faf2e0332cf2e2975e7bafc00f38f68 100644 (file)
@@ -34,21 +34,22 @@ static void ldapsrv_terminate_connection(struct ldapsrv_connection *ldap_conn, c
        server_terminate_connection(ldap_conn->connection, reason);
 }
 
+static const struct server_stream_ops *ldapsrv_get_stream_ops(void);
+
 /*
   add a socket address to the list of events, one event per port
 */
-static void add_socket(struct server_service *service, 
-                      const struct model_ops *model_ops, 
+static void add_socket(struct server_service *service,
                       struct ipv4_addr *ifip)
 {
-       struct server_socket *srv_sock;
+       struct server_stream_socket *stream_socket;
        uint16_t port = 389;
        char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
 
-       srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
+       stream_socket = service_setup_stream_socket(service, ldapsrv_get_stream_ops(), "ipv4", ip_str, &port);
 
        port = 3268;
-       srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
+       stream_socket = service_setup_stream_socket(service, ldapsrv_get_stream_ops(), "ipv4", ip_str, &port);
 
        talloc_free(ip_str);
 }
@@ -56,8 +57,7 @@ static void add_socket(struct server_service *service,
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
-static void ldapsrv_init(struct server_service *service,
-                        const struct model_ops *model_ops)
+static void ldapsrv_init(struct server_service *service)
 {      
        struct ldapsrv_service *ldap_service;
        struct ldapsrv_partition *part;
@@ -97,7 +97,7 @@ static void ldapsrv_init(struct server_service *service,
        ldap_service->default_partition = part;
        DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *);
 
-       service->private_data = ldap_service;
+       service->service.private_data = ldap_service;
 
        if (lp_interfaces() && lp_bind_interfaces_only()) {
                int num_interfaces = iface_count();
@@ -116,14 +116,14 @@ static void ldapsrv_init(struct server_service *service,
                                continue;
                        }
 
-                       add_socket(service, model_ops, ifip);
+                       add_socket(service, ifip);
                }
        } else {
                struct ipv4_addr ifip;
 
                /* Just bind to lp_socket_address() (usually 0.0.0.0) */
                ifip = interpret_addr2(lp_socket_address());
-               add_socket(service, model_ops, &ifip);
+               add_socket(service, &ifip);
        }
 }
 
@@ -423,7 +423,7 @@ NTSTATUS ldapsrv_flush_responses(struct ldapsrv_connection *conn)
 static void ldapsrv_recv(struct server_connection *conn, struct timeval t,
                         uint16_t flags)
 {
-       struct ldapsrv_connection *ldap_conn = conn->private_data;
+       struct ldapsrv_connection *ldap_conn = conn->connection.private_data;
        uint8_t *buf;
        size_t buf_length, msg_length;
        DATA_BLOB blob;
@@ -519,7 +519,7 @@ static void ldapsrv_recv(struct server_connection *conn, struct timeval t,
 static void ldapsrv_send(struct server_connection *conn, struct timeval t,
                         uint16_t flags)
 {
-       struct ldapsrv_connection *ldap_conn = conn->private_data;
+       struct ldapsrv_connection *ldap_conn = conn->connection.private_data;
 
        DEBUG(10,("ldapsrv_send\n"));
 
@@ -535,20 +535,6 @@ static void ldapsrv_send(struct server_connection *conn, struct timeval t,
        return;
 }
 
-/*
-  called when connection is idle
-*/
-static void ldapsrv_idle(struct server_connection *conn, struct timeval t)
-{
-       DEBUG(10,("ldapsrv_idle: not implemented!\n"));
-       return;
-}
-
-static void ldapsrv_close(struct server_connection *conn, const char *reason)
-{
-       return;
-}
-
 /*
   initialise a server_context from a open socket and register a event handler
   for reading from that socket
@@ -566,31 +552,31 @@ static void ldapsrv_accept(struct server_connection *conn)
 
        ZERO_STRUCTP(ldap_conn);
        ldap_conn->connection = conn;
-       ldap_conn->service = talloc_reference(ldap_conn, conn->service->private_data);
+       ldap_conn->service = talloc_reference(ldap_conn, conn->stream_socket->service);
 
-       conn->private_data = ldap_conn;
+       conn->connection.private_data = ldap_conn;
 
        return;
 }
 
-/*
-  called on a fatal error that should cause this server to terminate
-*/
-static void ldapsrv_exit(struct server_service *service, const char *reason)
+static const struct server_stream_ops ldap_stream_ops = {
+       .name                   = "ldap",
+       .socket_init            = NULL,
+       .accept_connection      = ldapsrv_accept,
+       .recv_handler           = ldapsrv_recv,
+       .send_handler           = ldapsrv_send,
+       .idle_handler           = NULL,
+       .close_connection       = NULL
+};
+
+static const struct server_stream_ops *ldapsrv_get_stream_ops(void)
 {
-       DEBUG(10,("ldapsrv_exit\n"));
-       return;
+       return &ldap_stream_ops;
 }
 
 static const struct server_service_ops ldap_server_ops = {
        .name                   = "ldap",
-       .service_init           = ldapsrv_init,
-       .accept_connection      = ldapsrv_accept,
-       .recv_handler           = ldapsrv_recv,
-       .send_handler           = ldapsrv_send,
-       .idle_handler           = ldapsrv_idle,
-       .close_connection       = ldapsrv_close,
-       .service_exit           = ldapsrv_exit, 
+       .service_init           = ldapsrv_init
 };
 
 const struct server_service_ops *ldapsrv_get_ops(void)
index 479d3395921a47ae34dfe94d9234518e1793c405..4b757e0be10f209ab446b5304aa8e2c55723e642 100644 (file)
@@ -134,7 +134,7 @@ static int pvfs_wait_destructor(void *ptr)
 
        pwait->private = private;
        pwait->handler = fn;
-       pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx;
+       pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging.ctx;
        pwait->ev = req->tcon->smb_conn->connection->event.ctx;
        pwait->msg_type = msg_type;
        pwait->req = talloc_reference(pwait, req);
index e5bdc3faae4b9bf7c8b944d5864ebb025802e087..0b642adb017357af8cc0638d02370ebfb0084f2e 100644 (file)
@@ -130,16 +130,16 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
        ntvfs->private_data = pvfs;
 
        pvfs->brl_context = brl_init(pvfs, 
-                                    pvfs->tcon->smb_conn->connection->server_id,  
+                                    pvfs->tcon->smb_conn->connection->connection.id,  
                                     pvfs->tcon->service,
-                                    pvfs->tcon->smb_conn->connection->messaging_ctx);
+                                    pvfs->tcon->smb_conn->connection->messaging.ctx);
        if (pvfs->brl_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
        pvfs->odb_context = odb_init(pvfs, 
-                                    pvfs->tcon->smb_conn->connection->server_id,  
-                                    pvfs->tcon->smb_conn->connection->messaging_ctx);
+                                    pvfs->tcon->smb_conn->connection->connection.id,  
+                                    pvfs->tcon->smb_conn->connection->messaging.ctx);
        if (pvfs->odb_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
index 282860b05a13c3f8772db95767cd2ed5cad9b4db..1fcd9a326127924e103b1ff5a9c90e83df63c2cd 100644 (file)
@@ -1220,7 +1220,7 @@ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_d
        return NT_STATUS_OK;
 }
 
-static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops)
+static void dcesrv_init(struct server_service *service)
 {
        NTSTATUS status;
        struct dcesrv_context *dce_ctx;
@@ -1235,7 +1235,9 @@ static void dcesrv_init(struct server_service *service, const struct model_ops *
                return;
        }
 
-       dcesrv_sock_init(service, model_ops, dce_ctx);
+       service->service.private_data = dce_ctx;
+
+       dcesrv_sock_init(service);
 
        return; 
 }
@@ -1257,18 +1259,6 @@ static void dcesrv_send(struct server_connection *srv_conn,
        dcesrv_sock_send(srv_conn, t, flags);
 }
 
-static void dcesrv_close(struct server_connection *srv_conn, const char *reason)
-{
-       dcesrv_sock_close(srv_conn, reason);
-       return; 
-}
-
-static void dcesrv_exit(struct server_service *service, const char *reason)
-{
-       dcesrv_sock_exit(service, reason);
-       return; 
-}
-
 /* the list of currently registered DCERPC endpoint servers.
  */
 static struct ep_server {
@@ -1350,15 +1340,24 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void)
        return &critical_sizes;
 }
 
-static const struct server_service_ops dcesrv_ops = {
+static const struct server_stream_ops dcesrv_stream_ops = {
        .name                   = "rpc",
-       .service_init           = dcesrv_init,
+       .socket_init            = NULL,
        .accept_connection      = dcesrv_accept,
        .recv_handler           = dcesrv_recv,
        .send_handler           = dcesrv_send,
        .idle_handler           = NULL,
-       .close_connection       = dcesrv_close,
-       .service_exit           = dcesrv_exit,
+       .close_connection       = NULL
+};
+
+const struct server_stream_ops *dcesrv_get_stream_ops(void)
+{
+       return &dcesrv_stream_ops;
+}
+
+static const struct server_service_ops dcesrv_ops = {
+       .name                   = "rpc",
+       .service_init           = dcesrv_init,
 };
 
 const struct server_service_ops *dcesrv_get_ops(void)
index 420c73cb1c0df76e9d450b67d84d9574df9183e2..561482a5fea67985ec665e0728130ae6112fb57f 100644 (file)
@@ -53,24 +53,22 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons
        server_terminate_connection(dce_conn->srv_conn, reason);
 }
 
-static void add_socket_rpc_unix(struct server_service *service,
-                               const struct model_ops *model_ops,
-                               struct dcesrv_context *dce_ctx,
-                               struct dcesrv_endpoint *e)
+static void add_socket_rpc_unix(struct server_service *service, struct dcesrv_endpoint *e)
 {
-       struct server_socket *sock;
+       struct dcesrv_context *dce_ctx = service->service.private_data;
+       struct server_stream_socket *stream_socket;
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 1;
 
-       sock = service_setup_socket(service,model_ops, "unix", e->ep_description.endpoint, &port);
-       if (!sock) {
-               DEBUG(0,("service_setup_socket(path=%s) failed\n",e->ep_description.endpoint));
+       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "unix", e->ep_description.endpoint, &port);
+       if (!stream_socket) {
+               DEBUG(0,("service_setup_stream_socket(path=%s) failed\n",e->ep_description.endpoint));
                return;
        }
 
-       dcesrv_sock = talloc_p(sock, struct dcesrv_socket_context);
+       dcesrv_sock = talloc_p(stream_socket, struct dcesrv_socket_context);
        if (!dcesrv_sock) {
-               DEBUG(0,("talloc_p(sock->mem_ctx, struct dcesrv_socket_context) failed\n"));
+               DEBUG(0,("talloc_p(stream_socket, struct dcesrv_socket_context) failed\n"));
                return;
        }
 
@@ -78,15 +76,13 @@ static void add_socket_rpc_unix(struct server_service *service,
        dcesrv_sock->endpoint           = e;
        dcesrv_sock->dcesrv_ctx         = dce_ctx;
 
-       sock->private_data = dcesrv_sock;
+       stream_socket->stream.private_data = dcesrv_sock;
 }
 
-static void add_socket_rpc_ncalrpc(struct server_service *service,
-                                                       const struct model_ops *model_ops,
-                                                       struct dcesrv_context *dce_ctx, 
-                                                       struct dcesrv_endpoint *e)
+static void add_socket_rpc_ncalrpc(struct server_service *service, struct dcesrv_endpoint *e)
 {
-       struct server_socket *sock;
+       struct dcesrv_context *dce_ctx = service->service.private_data;
+       struct server_stream_socket *stream_socket;
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 1;
        char *full_path;
@@ -100,15 +96,15 @@ static void add_socket_rpc_ncalrpc(struct server_service *service,
 
        full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description.endpoint);
 
-       sock = service_setup_socket(service,model_ops, "unix", full_path, &port);
-       if (!sock) {
-               DEBUG(0,("service_setup_socket(identifier=%s,path=%s) failed\n",e->ep_description.endpoint, full_path));
+       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "unix", full_path, &port);
+       if (!stream_socket) {
+               DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed\n",e->ep_description.endpoint, full_path));
                return;
        }
 
-       dcesrv_sock = talloc_p(sock, struct dcesrv_socket_context);
+       dcesrv_sock = talloc_p(stream_socket, struct dcesrv_socket_context);
        if (!dcesrv_sock) {
-               DEBUG(0,("talloc_p(sock->mem_ctx, struct dcesrv_socket_context) failed\n"));
+               DEBUG(0,("talloc_p(stream_socket, struct dcesrv_socket_context) failed\n"));
                return;
        }
 
@@ -116,7 +112,7 @@ static void add_socket_rpc_ncalrpc(struct server_service *service,
        dcesrv_sock->endpoint           = e;
        dcesrv_sock->dcesrv_ctx         = dce_ctx;
 
-       sock->private_data = dcesrv_sock;
+       stream_socket->stream.private_data = dcesrv_sock;
 
        return;
 }
@@ -125,12 +121,11 @@ static void add_socket_rpc_ncalrpc(struct server_service *service,
   add a socket address to the list of events, one event per dcerpc endpoint
 */
 static void add_socket_rpc_tcp_iface(struct server_service *service, 
-                                    const struct model_ops *model_ops,
-                                    struct dcesrv_context *dce_ctx, 
                                     struct dcesrv_endpoint *e,
                                     struct ipv4_addr *ifip)
 {
-       struct server_socket *sock;
+       struct dcesrv_context *dce_ctx = service->service.private_data;
+       struct server_stream_socket *stream_socket;
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 0;
        char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
@@ -138,9 +133,9 @@ static void add_socket_rpc_tcp_iface(struct server_service *service,
        if (e->ep_description.endpoint) 
                port = atoi(e->ep_description.endpoint);
 
-       sock = service_setup_socket(service,model_ops, "ipv4", ip_str, &port);
-       if (!sock) {
-               DEBUG(0,("service_setup_socket(port=%u) failed\n",port));
+       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "ipv4", ip_str, &port);
+       if (!stream_socket) {
+               DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed\n", ip_str, port));
                return;
        }
 
@@ -148,9 +143,9 @@ static void add_socket_rpc_tcp_iface(struct server_service *service,
                e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port);
        }
 
-       dcesrv_sock = talloc_p(sock, struct dcesrv_socket_context);
+       dcesrv_sock = talloc_p(stream_socket, struct dcesrv_socket_context);
        if (!dcesrv_sock) {
-               DEBUG(0,("talloc_p(sock->mem_ctx, struct dcesrv_socket_context) failed\n"));
+               DEBUG(0,("talloc_p(stream_socket, struct dcesrv_socket_context) failed\n"));
                return;
        }
 
@@ -158,17 +153,14 @@ static void add_socket_rpc_tcp_iface(struct server_service *service,
        dcesrv_sock->endpoint           = e;
        dcesrv_sock->dcesrv_ctx         = dce_ctx;
 
-       sock->private_data = dcesrv_sock;
+       stream_socket->stream.private_data = dcesrv_sock;
 
        talloc_free(ip_str);
 
        return;
 }
 
-static void add_socket_rpc_tcp(struct server_service *service,
-                                                       const struct model_ops *model_ops,
-                                                       struct dcesrv_context *dce_ctx, 
-                                                       struct dcesrv_endpoint *e)
+static void add_socket_rpc_tcp(struct server_service *service, struct dcesrv_endpoint *e)
 {
        /* Add TCP/IP sockets */
        if (lp_interfaces() && lp_bind_interfaces_only()) {
@@ -179,12 +171,12 @@ static void add_socket_rpc_tcp(struct server_service *service,
                        if (ifip == NULL) {
                                continue;
                        }
-                       add_socket_rpc_tcp_iface(service, model_ops, dce_ctx, e, ifip);
+                       add_socket_rpc_tcp_iface(service, e, ifip);
                }
        } else {
                struct ipv4_addr ifip;
                ifip = interpret_addr2(lp_socket_address());
-               add_socket_rpc_tcp_iface(service, model_ops, dce_ctx, e, &ifip);
+               add_socket_rpc_tcp_iface(service, e, &ifip);
        }
 
        return;
@@ -193,8 +185,9 @@ static void add_socket_rpc_tcp(struct server_service *service,
 /****************************************************************************
  Open the listening sockets for RPC over NCACN_IP_TCP/NCALRPC/NCACN_UNIX_STREAM
 ****************************************************************************/
-void dcesrv_sock_init(struct server_service *service, const struct model_ops *model_ops, struct dcesrv_context *dce_ctx)
+void dcesrv_sock_init(struct server_service *service)
 {
+       struct dcesrv_context *dce_ctx = service->service.private_data;
        struct dcesrv_endpoint *e;
 
        DEBUG(1,("dcesrv_sock_init\n"));
@@ -207,15 +200,15 @@ void dcesrv_sock_init(struct server_service *service, const struct model_ops *mo
        for (e=dce_ctx->endpoint_list;e;e=e->next) {
                switch (e->ep_description.transport) {
                case NCACN_UNIX_STREAM:
-                       add_socket_rpc_unix(service, model_ops, dce_ctx, e);
+                       add_socket_rpc_unix(service, e);
                        break;
                
                case NCALRPC:
-                       add_socket_rpc_ncalrpc(service, model_ops, dce_ctx, e);
+                       add_socket_rpc_ncalrpc(service, e);
                        break;
 
                case NCACN_IP_TCP:
-                       add_socket_rpc_tcp(service, model_ops, dce_ctx, e);
+                       add_socket_rpc_tcp(service, e);
                        break;
 
                default:
@@ -229,7 +222,7 @@ void dcesrv_sock_init(struct server_service *service, const struct model_ops *mo
 void dcesrv_sock_accept(struct server_connection *srv_conn)
 {
        NTSTATUS status;
-       struct dcesrv_socket_context *dcesrv_sock = srv_conn->server_socket->private_data;
+       struct dcesrv_socket_context *dcesrv_sock = srv_conn->stream_socket->stream.private_data;
        struct dcesrv_connection *dcesrv_conn = NULL;
 
        DEBUG(5,("dcesrv_sock_accept\n"));
@@ -245,7 +238,7 @@ void dcesrv_sock_accept(struct server_connection *srv_conn)
                return;
        }
 
-       srv_conn->private_data = dcesrv_conn;
+       srv_conn->connection.private_data = dcesrv_conn;
 
        return; 
 }
@@ -253,7 +246,7 @@ void dcesrv_sock_accept(struct server_connection *srv_conn)
 void dcesrv_sock_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
 {
        NTSTATUS status;
-       struct dcesrv_connection *dce_conn = conn->private_data;
+       struct dcesrv_connection *dce_conn = conn->connection.private_data;
        DATA_BLOB tmp_blob;
        size_t nread;
 
@@ -292,7 +285,7 @@ void dcesrv_sock_recv(struct server_connection *conn, struct timeval t, uint16_t
 
 void dcesrv_sock_send(struct server_connection *conn, struct timeval t, uint16_t flags)
 {
-       struct dcesrv_connection *dce_conn = conn->private_data;
+       struct dcesrv_connection *dce_conn = conn->connection.private_data;
        NTSTATUS status;
 
        DEBUG(10,("dcesrv_sock_send\n"));
@@ -309,20 +302,3 @@ void dcesrv_sock_send(struct server_connection *conn, struct timeval t, uint16_t
 
        return;
 }
-
-void dcesrv_sock_close(struct server_connection *conn, const char *reason)
-{
-       struct dcesrv_connection *dce_conn = conn->private_data;
-
-       DEBUG(5,("dcesrv_sock_close: %s\n",reason));
-
-       talloc_free(dce_conn);
-
-       return;
-}
-
-void dcesrv_sock_exit(struct server_service *service, const char *reason)
-{
-       DEBUG(1,("dcesrv_sock_exit: %s\n",reason));
-       return;
-}
index 77df978a05b6bbacd4dce09b0411855acbc26387..4af8fed53b177df9ba7582f80f4cee1a07cd900f 100644 (file)
@@ -144,7 +144,7 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(3), lp_maxmux());
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
-       SIVAL(req->out.vwv, VWV(6), req->smb_conn->pid);
+       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->connection.id);
        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
        SIVAL(req->out.vwv, VWV(11), 0); /* reserved */
@@ -198,7 +198,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(3), lp_maxmux());
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
-       SIVAL(req->out.vwv, VWV(6), req->smb_conn->pid);
+       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->connection.id);
        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
        SIVAL(req->out.vwv, VWV(11), 0);
@@ -310,7 +310,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */
        SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv);
        SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */
-       SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->pid); /* session key */
+       SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->connection.id); /* session key */
        SIVAL(req->out.vwv+1, VWV(9), capabilities);
        push_nttime(req->out.vwv+1, VWV(11), nttime);
        SSVALS(req->out.vwv+1,VWV(15), req->smb_conn->negotiate.zone_offset/60);
index 2ac832b439dc0b8bb9fe316cca0b1d313b13438c..f7f39f39d5925f8ddae759f5d78a381403eee224 100644 (file)
@@ -47,8 +47,6 @@ struct smbsrv_request *init_smb_request(struct smbsrv_connection *smb_conn)
 {
        struct smbsrv_request *req;
 
-       smb_conn->pkt_count++;
-
        req = talloc_p(smb_conn, struct smbsrv_request);
        if (!req) {
                return NULL;
index 1aa41d17a859a1bc9fd09eb986cbee2d093a9e2b..d4386ca77b7fef9d66ac5b2a5e4e776657d95903 100644 (file)
@@ -72,54 +72,6 @@ static int find_service(const char *service)
 
        iService = lp_servicenumber(service);
 
-       /* If we still don't have a service, attempt to add it as a printer. */
-       if (iService == -1) {
-               int iPrinterService;
-
-               if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
-                       const char *pszTemp;
-
-                       DEBUG(3,("checking whether %s is a valid printer name...\n", service));
-                       pszTemp = lp_printcapname();
-                       if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
-                               DEBUG(3,("%s is a valid printer name\n", service));
-                               DEBUG(3,("adding %s as a printer service\n", service));
-                               lp_add_printer(service, iPrinterService);
-                               iService = lp_servicenumber(service);
-                               if (iService < 0)
-                                       DEBUG(0,("failed to add %s as a printer service!\n", service));
-                       } else {
-                               DEBUG(3,("%s is not a valid printer name\n", service));
-                       }
-               }
-       }
-
-       /* Check for default vfs service?  Unsure whether to implement this */
-       if (iService == -1) {
-       }
-
-       /* just possibly it's a default service? */
-       if (iService == -1) {
-               const char *pdefservice = lp_defaultservice();
-               if (pdefservice && *pdefservice && 
-                   !strequal(pdefservice,service) &&
-                   !strstr(service,"..")) {
-                       /*
-                        * We need to do a local copy here as lp_defaultservice() 
-                        * returns one of the rotating lp_string buffers that
-                        * could get overwritten by the recursive find_service() call
-                        * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
-                        */
-                       pstring defservice;
-                       pstrcpy(defservice, pdefservice);
-                       iService = find_service(defservice);
-                       if (iService >= 0) {
-                               /* REWRITE: all_string_sub(service, "_","/",0); */
-                               iService = lp_add_service(service, iService);
-                       }
-               }
-       }
-
        if (iService >= 0 && !VALID_SNUM(iService)) {
                DEBUG(0,("Invalid snum %d for %s\n",iService, service));
                iService = -1;
index ddbaf43cc92299d1630bb56fea1bf83d0741cadc..1cbc831a173cdfac6b5ff88aeb9d873948695f1d 100644 (file)
@@ -506,7 +506,7 @@ static void switch_message(int type, struct smbsrv_request *req)
                session_tag = req->session->vuid;
        }
 
-       DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), smb_conn->connection->service->model_ops->get_id(req)));
+       DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), req->smb_conn->connection->connection.id));
 
        /* does this protocol need a valid tree connection? */
        if ((flags & AS_USER) && !req->tcon) {
@@ -649,21 +649,12 @@ void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char
        server_terminate_connection(smb_conn->connection, reason);
 }
 
-/*
-  called on a fatal error that should cause this server to terminate
-*/
-static void smbsrv_exit(struct server_service *service, const char *reason)
-{
-       DEBUG(1,("smbsrv_exit\n"));
-       return;
-}
+static const struct server_stream_ops *smbsrv_stream_ops(void);
 
 /*
   add a socket address to the list of events, one event per port
 */
-static void smb_add_socket(struct server_service *service, 
-                          const struct model_ops *model_ops,
-                          struct socket_context *socket_ctx, 
+static void smb_add_socket(struct server_service *service,
                           struct ipv4_addr *ifip)
 {
        const char **ports = lp_smb_ports();
@@ -673,7 +664,7 @@ static void smb_add_socket(struct server_service *service,
        for (i=0;ports[i];i++) {
                uint16_t port = atoi(ports[i]);
                if (port == 0) continue;
-               service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
+               service_setup_stream_socket(service, smbsrv_stream_ops(), "ipv4", ip_str, &port);
        }
 
        talloc_free(ip_str);
@@ -682,7 +673,7 @@ static void smb_add_socket(struct server_service *service,
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
-static void smbsrv_init(struct server_service *service, const struct model_ops *model_ops)
+static void smbsrv_init(struct server_service *service)
 {      
        DEBUG(1,("smbsrv_init\n"));
 
@@ -702,13 +693,13 @@ static void smbsrv_init(struct server_service *service, const struct model_ops *
                                continue;
                        }
 
-                       smb_add_socket(service, model_ops, NULL, ifip);
+                       smb_add_socket(service, ifip);
                }
        } else {
                struct ipv4_addr ifip;
                /* Just bind to lp_socket_address() (usually 0.0.0.0) */
                ifip = interpret_addr2(lp_socket_address());
-               smb_add_socket(service, model_ops, NULL, &ifip);
+               smb_add_socket(service, &ifip);
        }
 }
 
@@ -717,7 +708,7 @@ static void smbsrv_init(struct server_service *service, const struct model_ops *
 */
 static void smbsrv_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
 {
-       struct smbsrv_connection *smb_conn = conn->private_data;
+       struct smbsrv_connection *smb_conn = conn->connection.private_data;
        NTSTATUS status;
 
        DEBUG(10,("smbsrv_recv\n"));
@@ -738,7 +729,7 @@ static void smbsrv_recv(struct server_connection *conn, struct timeval t, uint16
 */
 static void smbsrv_send(struct server_connection *conn, struct timeval t, uint16_t flags)
 {
-       struct smbsrv_connection *smb_conn = conn->private_data;
+       struct smbsrv_connection *smb_conn = conn->connection.private_data;
 
        while (smb_conn->pending_send) {
                struct smbsrv_request *req = smb_conn->pending_send;
@@ -776,19 +767,9 @@ static void smbsrv_send(struct server_connection *conn, struct timeval t, uint16
        }
 }
 
-/*
-  called when connection is idle
-*/
-static void smbsrv_idle(struct server_connection *conn, struct timeval t)
-{
-       DEBUG(10,("smbsrv_idle: not implemented!\n"));
-       conn->event.idle->next_event = timeval_add(&t, 5, 0);
-       return;
-}
-
 static void smbsrv_close(struct server_connection *conn, const char *reason)
 {
-       struct smbsrv_connection *smb_conn = conn->private_data;
+       struct smbsrv_connection *smb_conn = conn->connection.private_data;
 
        DEBUG(5,("smbsrv_close: %s\n",reason));
 
@@ -818,7 +799,7 @@ void smbd_process_async(struct smbsrv_connection *smb_conn)
   initialise a server_context from a open socket and register a event handler
   for reading from that socket
 */
-void smbsrv_accept(struct server_connection *conn)
+static void smbsrv_accept(struct server_connection *conn)
 {
        struct smbsrv_connection *smb_conn;
 
@@ -827,10 +808,6 @@ void smbsrv_accept(struct server_connection *conn)
        smb_conn = talloc_zero_p(conn, struct smbsrv_connection);
        if (!smb_conn) return;
 
-       smb_conn->pid = getpid();
-
-       sub_set_context(&smb_conn->substitute);
-
        /* now initialise a few default values associated with this smb socket */
        smb_conn->negotiate.max_send = 0xFFFF;
 
@@ -848,20 +825,29 @@ void smbsrv_accept(struct server_connection *conn)
 
        smb_conn->connection = conn;
 
-       conn->private_data = smb_conn;
+       conn->connection.private_data = smb_conn;
 
        return;
 }
 
-static const struct server_service_ops smb_server_ops = {
+static const struct server_stream_ops smb_stream_ops = {
        .name                   = "smb",
-       .service_init           = smbsrv_init,
+       .socket_init            = NULL,
        .accept_connection      = smbsrv_accept,
        .recv_handler           = smbsrv_recv,
        .send_handler           = smbsrv_send,
-       .idle_handler           = smbsrv_idle,
-       .close_connection       = smbsrv_close,
-       .service_exit           = smbsrv_exit,  
+       .idle_handler           = NULL,
+       .close_connection       = smbsrv_close
+};
+
+static const struct server_stream_ops *smbsrv_stream_ops(void)
+{
+       return &smb_stream_ops;
+}
+
+static const struct server_service_ops smb_server_ops = {
+       .name                   = "smb",
+       .service_init           = smbsrv_init,  
 };
 
 const struct server_service_ops *smbsrv_get_ops(void)
index 8a21051b65c2072580ec2d12b12c892517a7ba4b..01eb63d01c674424f9438eb4835f0a6989f51ec1 100644 (file)
@@ -150,7 +150,7 @@ struct substitute_context {
 struct smbsrv_connection {
        /* a count of the number of packets we have received. We
         * actually only care about zero/non-zero at this stage */
-       unsigned pkt_count;
+       //unsigned pkt_count;
 
        /* context that has been negotiated between the client and server */
        struct {
@@ -213,6 +213,7 @@ struct smbsrv_connection {
        } tree;
 
        /* the context associated with open files on an smb socket */
+#if 0
        struct {
                struct files_struct *files; /* open files */
        
@@ -228,7 +229,7 @@ struct smbsrv_connection {
                /* limit for maximum open files */
                int real_max_open_files;
        } file;
-
+#endif
        /* context associated with currently valid session setups */
        struct {
                /* this holds info on session vuids that are already validated for this VC */
@@ -237,11 +238,6 @@ struct smbsrv_connection {
                int num_validated_vuids;
        } sessions;
 
-       /* this holds long term state specific to the printing subsystem */
-       struct {
-               struct notify_queue *notify_queue_head;
-       } print;
-
        /* the server_context holds a linked list of pending requests,
         * this is used for blocking locks and requests blocked due to oplock
         * break requests */
@@ -251,7 +247,7 @@ struct smbsrv_connection {
                /* the request itself - needs to be freed */
                struct smbsrv_request *request;
        } *requests;
-
+#if 0
        /* the timers context contains info on when we last did various
         * functions */
        struct {
@@ -264,13 +260,10 @@ struct smbsrv_connection {
                /* when we last checked the smb.conf for auto-reload */
                time_t last_smb_conf_reload;
        } timers;
-
+#endif
        struct smb_signing_context signing;
 
-       struct substitute_context substitute;
-
-       /* the pid of the process handling this session */
-       pid_t pid;
+//     struct substitute_context substitute;
        
        struct server_connection *connection;
 
index df421326d8897993a3be1c147a273b1b65ce2a9f..cd2fb4ab725bcba5fe4539e50c820b64b26c787b 100644 (file)
@@ -50,24 +50,15 @@ REQUIRED_SUBSYSTEMS = \
 # End SUBSYSTEM SERVER
 #######################
 
-#######################
-# Start SUBSYSTEM SERVER
-[SUBSYSTEM::SERVER]
-INIT_OBJ_FILES = \
-               smbd/server.o
-ADD_OBJ_FILES = \
-               smbd/rewrite.o
-REQUIRED_SUBSYSTEMS = \
-               PROCESS_MODEL \
-               SERVER_SERVICE
-# End SUBSYSTEM SERVER
-#######################
-
 #################################
 # Start BINARY smbd
 [BINARY::smbd]
+OBJ_FILES = \
+               smbd/server.o \
+               smbd/rewrite.o
 REQUIRED_SUBSYSTEMS = \
-               SERVER \
+               PROCESS_MODEL \
+               SERVER_SERVICE \
                CONFIG \
                LIBCMDLINE \
                LIBBASIC
index ad9a26d377598d579c4b68e94685181793221eb6..f2abfd0a497f42b6acce12fe095aeab250226bcc 100644 (file)
@@ -27,7 +27,7 @@
 /*
   setup the events for the chosen process model
 */
-const struct model_ops *process_model_startup(const char *model)
+const struct model_ops *process_model_startup(struct server_context *srv_ctx, const char *model)
 {
        const struct model_ops *ops;
 
@@ -37,7 +37,7 @@ const struct model_ops *process_model_startup(const char *model)
                exit(-1);
        }
 
-       ops->model_startup();
+       ops->model_init(srv_ctx);
 
        return ops;
 }
index 92d92a70ad81f3b372397cb168271c90aff290f1..fb9bdfd44b97f10843c66087da1d16291110deef 100644 (file)
@@ -3,7 +3,7 @@
    process model manager - main loop
    Copyright (C) Andrew Tridgell 1992-2003
    Copyright (C) James J Myers 2003 <myersjj@samba.org>
-   Copyright (C) Stefan (metze) Metzmacher 2004
+   Copyright (C) Stefan (metze) Metzmacher 2004-2005
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -37,21 +37,23 @@ struct model_ops {
        const char *name;
 
        /* called at startup when the model is selected */
-       void (*model_startup)(void);
+       void (*model_init)(struct server_context *srv_ctx);
+       /* called at th eend of the main server process */
+       void (*model_exit)(struct server_context *srv_ctx, const char *reason);
+
 
        /* function to accept new connection */
        void (*accept_connection)(struct event_context *, struct fd_event *, 
                                  struct timeval t, uint16_t);
-                       
        /* function to terminate a connection */
        void (*terminate_connection)(struct server_connection *srv_conn, 
                                     const char *reason);
 
-       /* function to exit server */
-       void (*exit_server)(struct server_context *srv_ctx, const char *reason);
 
-       /* returns process or thread id */
-       int (*get_id)(struct smbsrv_request *req);
+       /* function to create a new task event_context */
+       void (*create_task)(struct server_task *task);
+       /* function to exit this task */
+       void (*terminate_task)(struct server_task *task, const char *reason);
 };
 
 /* this structure is used by modules to determine the size of some critical types */
index da234703030316e7ed85437f0cf123f8a425df87..6a00ad237fd5bcb4c278e4bf6e25d2cef78b5d96 100644 (file)
 /*
   called when the process model is selected
 */
-static void single_start_server(void)
+static void single_model_init(struct server_context *server)
 {
-       smbd_process_init();
+}
+
+static void single_model_exit(struct server_context *server, const char *reason)
+{
+       DEBUG(1,("single_exit_server: reason[%s]\n",reason));
+       talloc_free(server);
+       exit(0);
 }
 
 /*
@@ -43,18 +49,18 @@ static void single_accept_connection(struct event_context *ev, struct fd_event *
 {
        NTSTATUS status;
        struct socket_context *sock;
-       struct server_socket *server_socket = srv_fde->private;
+       struct server_stream_socket *stream_socket = srv_fde->private;
        struct server_connection *conn;
 
        /* accept an incoming connection. */
-       status = socket_accept(server_socket->socket, &sock);
+       status = socket_accept(stream_socket->socket, &sock);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("accept_connection_single: accept: %s\n",
                         nt_errstr(status)));
                return;
        }
 
-       conn = server_setup_connection(ev, server_socket, sock, t, socket_get_fd(sock));
+       conn = server_setup_connection(ev, stream_socket, sock, t, socket_get_fd(sock));
        if (!conn) {
                DEBUG(10,("server_setup_connection failed\n"));
                return;
@@ -62,8 +68,6 @@ static void single_accept_connection(struct event_context *ev, struct fd_event *
 
        talloc_steal(conn, sock);
 
-       DLIST_ADD(server_socket->connection_list,conn);
-
        /* return to event handling */
        return;
 }
@@ -80,38 +84,57 @@ static void single_terminate_connection(struct server_connection *conn, const ch
        }
 }
 
-static int single_get_id(struct smbsrv_request *req)
+/*
+  called to create a new event context for a new task
+*/
+static void single_create_task(struct server_task *task)
 {
-       return (int)req->smb_conn->pid;
+       task->task.id   = (uint32_t)task;
+       task->event.ctx = task->service->server->event.ctx;
+
+       /* setup to receive internal messages on this connection */
+       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
+       if (!task->messaging.ctx) {
+               server_terminate_task(task, "messaging_init() failed");
+               return;
+       }
+
+       task->task.ops->task_init(task);
+       return;
 }
 
-static void single_exit_server(struct server_context *srv_ctx, const char *reason)
+/*
+  called to exit from a server_task
+*/
+static void single_terminate_task(struct server_task *task, const char *reason)
 {
        DEBUG(1,("single_exit_server: reason[%s]\n",reason));
+       talloc_free(task);
+       return;
 }
 
+static const struct model_ops single_ops = {
+       .name                   = "single",
+
+       .model_init             = single_model_init,
+       .model_exit             = single_model_exit,
+
+       .accept_connection      = single_accept_connection,
+       .terminate_connection   = single_terminate_connection,
+
+       .create_task            = single_create_task,
+       .terminate_task         = single_terminate_task
+};
+
 /*
   initialise the single process model, registering ourselves with the process model subsystem
  */
 NTSTATUS process_model_single_init(void)
 {
        NTSTATUS ret;
-       struct model_ops ops;
-
-       ZERO_STRUCT(ops);
-
-       /* fill in our name */
-       ops.name = "single";
-
-       /* fill in all the operations */
-       ops.model_startup               = single_start_server;
-       ops.accept_connection           = single_accept_connection;
-       ops.terminate_connection        = single_terminate_connection;
-       ops.exit_server                 = single_exit_server;
-       ops.get_id                      = single_get_id;
 
        /* register ourselves with the PROCESS_MODEL subsystem. */
-       ret = register_process_model(&ops);
+       ret = register_process_model(&single_ops);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("Failed to register process_model 'single'!\n"));
                return ret;
index 3612c6a7f47cc14075b75bfab994c61ca08e6064..b0f7cf1a11133b283936806efcbd849c2e0dffac 100644 (file)
 /*
   called when the process model is selected
 */
-static void standard_model_startup(void)
+static void standard_model_init(struct server_context *server)
 {
        signal(SIGCHLD, SIG_IGN);
-       smbd_process_init();
+}
+
+static void standard_model_exit(struct server_context *server, const char *reason)
+{
+       DEBUG(1,("standard_model_exit: reason[%s]\n",reason));
+       talloc_free(server);
+       exit(0);
 }
 
 /*
@@ -43,12 +49,12 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
 {
        NTSTATUS status;
        struct socket_context *sock;
-       struct server_socket *server_socket = srv_fde->private;
+       struct server_stream_socket *stream_socket = srv_fde->private;
        struct server_connection *conn;
        pid_t pid;
 
        /* accept an incoming connection. */
-       status = socket_accept(server_socket->socket, &sock);
+       status = socket_accept(stream_socket->socket, &sock);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("standard_accept_connection: accept: %s\n",
                         nt_errstr(status)));
@@ -68,7 +74,7 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
        /* Child code ... */
 
        /* close all the listening sockets */
-       service_close_listening_sockets(server_socket->service->srv_ctx);
+       event_remove_fd_all_handler(ev, server_accept_handler);
 
        /* we don't care if the dup fails, as its only a select()
           speed optimisation */
@@ -83,16 +89,15 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
 
        set_need_random_reseed();
 
-       conn = server_setup_connection(ev, server_socket, sock, t, getpid());
+       conn = server_setup_connection(ev, stream_socket, sock, t, getpid());
        if (!conn) {
                DEBUG(0,("server_setup_connection(ev, server_socket, sock, t) failed\n"));
+               exit(1);
                return;
        }
 
        talloc_steal(conn, sock);
 
-       DLIST_ADD(server_socket->connection_list,conn);
-
        /* return to the event loop */
 }
 
@@ -103,7 +108,7 @@ static void standard_terminate_connection(struct server_connection *conn, const
        DEBUG(2,("standard_terminate_connection: reason[%s]\n",reason));
 
        if (conn) {
-               talloc_free(conn->service->srv_ctx);
+               talloc_free(conn->stream_socket->service->server);
        }
 
        /* this init_iconv() has the effect of freeing the iconv context memory,
@@ -117,38 +122,94 @@ static void standard_terminate_connection(struct server_connection *conn, const
        exit(0);
 }
 
-static int standard_get_id(struct smbsrv_request *req)
+/*
+  called to create a new event context for a new task
+*/
+static void standard_create_task(struct server_task *task)
 {
-       return (int)req->smb_conn->pid;
+       pid_t pid;
+
+       pid = fork();
+
+       if (pid != 0) {
+               /* parent or error code ... */
+               talloc_free(task);
+               /* go back to the event loop */
+               return;
+       }
+
+       /* Child code ... */
+
+       /* close all the listening sockets */
+       event_remove_fd_all_handler(task->service->server->event.ctx, server_accept_handler);
+
+       /* tdb needs special fork handling */
+       if (tdb_reopen_all() == -1) {
+               DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n"));
+       }
+
+       /* Ensure that the forked children do not expose identical random streams */
+
+       set_need_random_reseed();
+
+       task->task.id   = (uint32)getpid();
+       task->event.ctx = task->service->server->event.ctx;
+
+       /* setup to receive internal messages on this connection */
+       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
+       if (!task->messaging.ctx) {
+               server_terminate_task(task, "messaging_init() failed");
+               return;
+       }
+
+       task->task.ops->task_init(task);
+
+       server_terminate_task(task, "exit");
+       return;
 }
 
-static void standard_exit_server(struct server_context *srv_ctx, const char *reason)
+/*
+  called to destroy a new event context for a new task
+*/
+static void standard_terminate_task(struct server_task *task, const char *reason)
 {
-       DEBUG(1,("standard_exit_server: reason[%s]\n",reason));
+       DEBUG(2,("standard_terminate_task: reason[%s]\n",reason));
+
+       talloc_free(task);
+
+       /* this init_iconv() has the effect of freeing the iconv context memory,
+          which makes leak checking easier */
+       init_iconv();
+
+       /* the secrets db should really hang off the connection structure */
+       secrets_shutdown();
+
+       /* terminate this process */
+       exit(0);
 }
 
+static const struct model_ops standard_ops = {
+       .name                   = "standard",
+
+       .model_init             = standard_model_init,
+       .model_exit             = standard_model_exit,
+
+       .accept_connection      = standard_accept_connection,
+       .terminate_connection   = standard_terminate_connection,
+
+       .create_task            = standard_create_task,
+       .terminate_task         = standard_terminate_task
+};
+
 /*
   initialise the standard process model, registering ourselves with the process model subsystem
  */
 NTSTATUS process_model_standard_init(void)
 {
        NTSTATUS ret;
-       struct model_ops ops;
-
-       ZERO_STRUCT(ops);
-
-       /* fill in our name */
-       ops.name = "standard";
-
-       /* fill in all the operations */
-       ops.model_startup = standard_model_startup;
-       ops.accept_connection = standard_accept_connection;
-       ops.terminate_connection = standard_terminate_connection;
-       ops.exit_server = standard_exit_server;
-       ops.get_id = standard_get_id;
 
        /* register ourselves with the PROCESS_MODEL subsystem. */
-       ret = register_process_model(&ops);
+       ret = register_process_model(&standard_ops);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("Failed to register process_model 'standard'!\n"));
                return ret;
index 8e8ee23aaf2d6616c5f86df13284f769db1508d1..f0e98221aec4fa3b72175e3683544fe7c45e4861 100644 (file)
 
 static void *thread_connection_fn(void *thread_parm)
 {
-       struct event_context *ev = thread_parm;
+       struct server_connection *conn = thread_parm;
+
+       conn->connection.id = pthread_self();
+
        /* wait for action */
-       event_loop_wait(ev);
+       event_loop_wait(conn->event.ctx);
 
 #if 0
        pthread_cleanup_pop(1);  /* will invoke terminate_mt_connection() */
@@ -43,11 +46,6 @@ static void *thread_connection_fn(void *thread_parm)
        return NULL;
 }
 
-static int thread_get_id(struct smbsrv_request *req)
-{
-       return (int)pthread_self();
-}
-
 /*
   called when a listening socket becomes readable
 */
@@ -59,15 +57,15 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
        int rc;
        pthread_t thread_id;
        pthread_attr_t thread_attr;
-       struct server_socket *server_socket = srv_fde->private;
+       struct server_stream_socket *stream_socket = srv_fde->private;
        struct server_connection *conn;
 
        /* accept an incoming connection. */
-       status = socket_accept(server_socket->socket, &sock);
+       status = socket_accept(stream_socket->socket, &sock);
        if (!NT_STATUS_IS_OK(status)) {
                return;
        }
-       
+
        /* create new detached thread for this connection.  The new
           thread gets a new event_context with a single fd_event for
           receiving from the new socket. We set that thread running
@@ -75,13 +73,13 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
           main event_context is continued.
        */
 
-       ev = event_context_init(server_socket);
+       ev = event_context_init(stream_socket);
        if (!ev) {
                socket_destroy(sock);
-               return; 
+               return;
        }
 
-       conn = server_setup_connection(ev, server_socket, sock, t, pthread_self());
+       conn = server_setup_connection(ev, stream_socket, sock, t, -1);
        if (!conn) {
                event_context_destroy(ev);
                socket_destroy(sock);
@@ -91,16 +89,9 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
        talloc_steal(conn, ev);
        talloc_steal(conn, sock);
 
-       /* TODO: is this MUTEX_LOCK in the right place here?
-        *       --metze
-        */
-       MUTEX_LOCK_BY_ID(MUTEX_SMBD);
-       DLIST_ADD(server_socket->connection_list,conn);
-       MUTEX_UNLOCK_BY_ID(MUTEX_SMBD);
-       
        pthread_attr_init(&thread_attr);
        pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
-       rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, ev);
+       rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, conn);
        pthread_attr_destroy(&thread_attr);
        if (rc == 0) {
                DEBUG(4,("accept_connection_thread: created thread_id=%lu for fd=%d\n", 
@@ -414,7 +405,7 @@ static void thread_fault_handler(int sig)
 /*
   called when the process model is selected
 */
-static void thread_model_startup(void)
+static void thread_model_init(struct server_context *server)
 {
        struct mutex_ops m_ops;
        struct debug_ops d_ops;
@@ -422,8 +413,6 @@ static void thread_model_startup(void)
        ZERO_STRUCT(m_ops);
        ZERO_STRUCT(d_ops);
 
-       smbd_process_init();
-
        /* register mutex/rwlock handlers */
        m_ops.mutex_init = thread_mutex_init;
        m_ops.mutex_lock = thread_mutex_lock;
@@ -448,33 +437,100 @@ static void thread_model_startup(void)
        register_debug_handlers("thread", &d_ops);      
 }
 
-static void thread_exit_server(struct server_context *srv_ctx, const char *reason)
+static void thread_model_exit(struct server_context *server, const char *reason)
 {
-       DEBUG(1,("thread_exit_server: reason[%s]\n",reason));
+       DEBUG(1,("thread_model_exit: reason[%s]\n",reason));
+       talloc_free(server);
+       exit(0);
 }
 
+static void *thread_task_fn(void *thread_parm)
+{
+       struct server_task *task = thread_parm;
+
+       task->task.id = pthread_self();
+
+       task->event.ctx = event_context_init(task);
+       if (!task->event.ctx) {
+               server_terminate_task(task, "event_context_init() failed");
+               return NULL; 
+       }
+
+       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
+       if (!task->messaging.ctx) {
+               server_terminate_task(task, "messaging_init() failed");
+               return NULL;
+       }
+
+       task->task.ops->task_init(task);
+
+       /* wait for action */
+       event_loop_wait(task->event.ctx);
+
+       server_terminate_task(task, "exit");
+#if 0
+       pthread_cleanup_pop(1);  /* will invoke terminate_mt_connection() */
+#endif
+       return NULL;
+}
+/*
+  called to create a new event context for a new task
+*/
+static void thread_create_task(struct server_task *task)
+{
+       int rc;
+       pthread_t thread_id;
+       pthread_attr_t thread_attr;
+
+       pthread_attr_init(&thread_attr);
+       pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+       rc = pthread_create(&thread_id, &thread_attr, thread_task_fn, task);
+       pthread_attr_destroy(&thread_attr);
+       if (rc == 0) {
+               DEBUG(4,("thread_create_task: created thread_id=%lu for task='%s'\n", 
+                       (unsigned long int)thread_id, task->task.ops->name));
+       } else {
+               DEBUG(0,("thread_create_task: thread create failed for task='%s', rc=%d\n", task->task.ops->name, rc));
+               return;
+       }
+       return;
+}
+
+/*
+  called to destroy a new event context for a new task
+*/
+static void thread_terminate_task(struct server_task *task, const char *reason)
+{
+       DEBUG(2,("thread_terminate_task: reason[%s]\n",reason));
+
+       talloc_free(task);
+
+       /* terminate this thread */
+       pthread_exit(NULL);  /* thread cleanup routine will do actual cleanup */
+}
+
+static const struct model_ops thread_ops = {
+       .name                   = "thread",
+
+       .model_init             = thread_model_init,
+       .model_exit             = thread_model_exit,
+
+       .accept_connection      = thread_accept_connection,
+       .terminate_connection   = thread_terminate_connection,
+
+       .create_task            = thread_create_task,
+       .terminate_task         = thread_terminate_task
+};
+
 /*
   initialise the thread process model, registering ourselves with the model subsystem
  */
 NTSTATUS process_model_thread_init(void)
 {
        NTSTATUS ret;
-       struct model_ops ops;
-
-       ZERO_STRUCT(ops);
-
-       /* fill in our name */
-       ops.name = "thread";
-
-       /* fill in all the operations */
-       ops.model_startup = thread_model_startup;
-       ops.accept_connection = thread_accept_connection;
-       ops.terminate_connection = thread_terminate_connection;
-       ops.exit_server = thread_exit_server;
-       ops.get_id = thread_get_id;
 
        /* register ourselves with the PROCESS_MODEL subsystem. */
-       ret = register_process_model(&ops);
+       ret = register_process_model(&thread_ops);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("Failed to register process_model 'thread'!\n"));
                return ret;
index 8e7ddc405e6b0bae482455a3d0c5f03fb296ad2b..7128a0ad0d69430cf752e95ac69938ead53cd5e3 100644 (file)
@@ -1,14 +1,6 @@
 #include "includes.h"
 #include "dynconfig.h"
 
-/*
-
- this is a set of temporary stub functions used during the core smbd rewrite.
- This file will need to go away before the rewrite is complete
-*/
-
-BOOL pcap_printername_ok(const char *service, const char *foo)
-{ return True; }
 
 /*
  * initialize an smb process. Guaranteed to be called only once per
index 830d26fa7f99357f957fb20893ec5fd89e63bcf4..369391bdbfa51c60a919db43df473f7f2c55cc7f 100644 (file)
 #include "includes.h"
 #include "lib/cmdline/popt_common.h"
 
-static void exit_server(const char *reason)
-{
-       DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
-       exit(0);
-}
-
 /****************************************************************************
  main server.
 ****************************************************************************/
@@ -41,10 +35,10 @@ static int binary_smbd_main(int argc,const char *argv[])
        BOOL log_stdout = False;
        int opt;
        poptContext pc;
-       struct server_context *srv_ctx;
+       struct server_context *server;
        const char *model = "standard";
        struct poptOption long_options[] = {
-               POPT_AUTOHELP
+       POPT_AUTOHELP
        POPT_COMMON_SAMBA
        {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" , NULL },
        {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)", NULL},
@@ -52,6 +46,7 @@ static int binary_smbd_main(int argc,const char *argv[])
        {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout", NULL },
        {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports", "PORTS"},
        {"model", 'M', POPT_ARG_STRING, &model, True, "Select process model", "MODEL"},
+       POPT_COMMON_VERSION
        POPT_TABLEEND
        };
        
@@ -77,7 +72,7 @@ static int binary_smbd_main(int argc,const char *argv[])
        }
        setup_logging(argv[0], log_stdout?DEBUG_STDOUT:DEBUG_FILE);
 
-       fault_setup((void (*)(void *))exit_server);
+       fault_setup(NULL);
        
        /* we are never interested in SIGPIPE */
        BlockSignals(True,SIGPIPE);
@@ -105,7 +100,7 @@ static int binary_smbd_main(int argc,const char *argv[])
        reopen_logs();
 
        DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
-       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
+       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
 
        if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
@@ -142,15 +137,21 @@ static int binary_smbd_main(int argc,const char *argv[])
 
        init_subsystems();
 
+       smbd_process_init();
+
        DEBUG(0,("Using %s process model\n", model));
-       srv_ctx = server_service_startup(model);
-       if (!srv_ctx) {
+       server = server_service_startup(model, lp_server_services());
+       if (!server) {
                DEBUG(0,("Starting Services failed.\n"));
                return 1;
        }
 
        /* wait for events */
-       return event_loop_wait(srv_ctx->events);
+       event_loop_wait(server->event.ctx);
+
+       server_service_shutdown(server, "exit");
+
+       return 0;
 }
 
  int main(int argc, const char *argv[])
index e76adec44dc82d0e84bcee6c392b29733cca68da..6021df12c59abfc10c0d85e755a502494e3fa2c8 100644 (file)
@@ -25,8 +25,15 @@ struct server_service;
 struct event_context;
 
 struct server_context {
+       struct {
+               struct event_context *ctx;
+       } event;
+
+       struct {
+               const struct model_ops *ops;
+       } model;
+
        struct server_service *service_list;
-       struct event_context *events;
 };
 
 /* size of listen() backlog in smbd */
index 586c05c2c63ca10b4a49db6e6df9bff8b01ad5dc..e0ec3cf07e2483bc3bd08a7685e0dc6d14c29b24 100644 (file)
 #include "dlinklist.h"
 #include "process_model.h"
 
-struct server_context *server_service_startup(const char *model)
+struct server_context *server_service_startup(const char *model, const char **server_services)
 {
        int i;
-       const char **server_services = lp_server_services();
-       struct server_context *srv_ctx;
-       const struct model_ops *model_ops;
+       struct server_context *server;
 
        if (!server_services) {
-               DEBUG(0,("process_model_startup: no endpoint servers configured\n"));
+               DEBUG(0,("server_service_startup: no endpoint servers configured\n"));
                return NULL;
        }
 
-       model_ops = process_model_startup(model);
-       if (!model_ops) {
-               DEBUG(0,("process_model_startup('%s') failed\n", model));
-               return NULL;
-       }
-
-       srv_ctx = talloc_p(NULL, struct server_context);
-       if (!srv_ctx) {
+       server = talloc_zero(NULL, struct server_context);
+       if (!server) {
                return NULL;    
        }
 
-       ZERO_STRUCTP(srv_ctx);
+       server->model.ops = process_model_startup(server, model);
+       if (!server->model.ops) {
+               DEBUG(0,("process_model_startup('%s') failed\n", model));
+               return NULL;
+       }
 
-       srv_ctx->events = event_context_init(srv_ctx);
-       if (!srv_ctx->events) {
+       server->event.ctx = event_context_init(server);
+       if (!server->event.ctx) {
                DEBUG(0,("event_context_init() failed\n"));
-               return NULL;    
+               return NULL;
        }
 
-
        for (i=0;server_services[i];i++) {
                const struct server_service_ops *service_ops;
                struct server_service *service;
@@ -69,63 +64,64 @@ struct server_context *server_service_startup(const char *model)
                        return NULL;
                }
 
-               service = talloc_p(srv_ctx, struct server_service);
+               service = talloc_zero(server, struct server_service);
                if (!service) {
                        return NULL;
                }
 
-               ZERO_STRUCTP(service);
-               service->ops            = service_ops;
-               service->model_ops      = model_ops;
-               service->srv_ctx        = srv_ctx;
-               
+               service->service.ops    = service_ops;
+               service->server         = server;
+
                /* TODO: service_init() should return a result */
-               service->ops->service_init(service, model_ops);
+               service->service.ops->service_init(service);
 
-               DLIST_ADD(srv_ctx->service_list, service);
+               DLIST_ADD(server->service_list, service);
        }
 
-       return srv_ctx;
+       return server;
+}
+
+void server_service_shutdown(struct server_context *server, const char *reason)
+{
+       server->model.ops->model_exit(server, reason);
 }
 
 /*
   setup a listen stream socket
   if you pass *port == 0, then a port > 1024 is used
  */
-struct server_socket *service_setup_socket(struct server_service *service,
-                                          const struct model_ops *model_ops,
-                                          const char *family,
-                                          const char *sock_addr,
-                                          uint16_t *port)
+struct server_stream_socket *service_setup_stream_socket(struct server_service *service,
+                                                        const struct server_stream_ops *stream_ops,
+                                                        const char *family,
+                                                        const char *sock_addr,
+                                                        uint16_t *port)
 {
        NTSTATUS status;
-       struct server_socket *srv_sock;
-       struct socket_context *socket_ctx;
+       struct server_stream_socket *stream_socket;
+       struct socket_context *sock;
        struct fd_event fde;
        int i;
 
-       status = socket_create(family, SOCKET_TYPE_STREAM, &socket_ctx, 0);
+       status = socket_create(family, SOCKET_TYPE_STREAM, &sock, 0);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to open socket on %s:%u - %s\n",
                        sock_addr, *port, nt_errstr(status)));
                return NULL;
        }
 
-       talloc_steal(service, socket_ctx);
-
        /* ready to listen */
-       status = socket_set_option(socket_ctx, "SO_KEEPALIVE SO_REUSEADDR=1", NULL);
+       status = socket_set_option(sock, "SO_KEEPALIVE SO_REUSEADDR=1", NULL);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("socket_set_option(socket_ctx, SO_KEEPALIVE, NULL): %s\n",
                        nt_errstr(status)));
-               socket_destroy(socket_ctx);
+               socket_destroy(sock);
                return NULL;
        }
-       status = socket_set_option(socket_ctx, lp_socket_options(), NULL);
+       status = socket_set_option(sock, lp_socket_options(), NULL);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("socket_set_option(socket_ctx, lp_socket_options(), NULL): %s\n",
                        nt_errstr(status)));
-               socket_destroy(socket_ctx);
+               socket_destroy(sock);
                return NULL;
        }
 
@@ -133,64 +129,70 @@ struct server_socket *service_setup_socket(struct server_service *service,
 
        if (*port == 0) {
                for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) {
-                       status = socket_listen(socket_ctx, sock_addr, i, SERVER_LISTEN_BACKLOG, 0);
+                       status = socket_listen(sock, sock_addr, i, SERVER_LISTEN_BACKLOG, 0);
                        if (NT_STATUS_IS_OK(status)) {
                                *port = i;
                                break;
                        }
                }
        } else {
-               status = socket_listen(socket_ctx, sock_addr, *port, SERVER_LISTEN_BACKLOG, 0);
+               status = socket_listen(sock, sock_addr, *port, SERVER_LISTEN_BACKLOG, 0);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to listen on %s:%u - %s\n",
                        sock_addr, *port, nt_errstr(status)));
-               socket_destroy(socket_ctx);
+               socket_destroy(sock);
                return NULL;
        }
 
-       srv_sock = talloc_p(service, struct server_socket);
-       if (!srv_sock) {
-               DEBUG(0,("talloc_p(mem_ctx, struct server_socket) failed\n"));
-               socket_destroy(socket_ctx);
+       stream_socket = talloc_zero(service, struct server_stream_socket);
+       if (!stream_socket) {
+               DEBUG(0,("talloc_p(mem_ctx, struct server_stream_socket) failed\n"));
+               socket_destroy(sock);
                return NULL;
        }
 
        /* we are only interested in read events on the listen socket */
-       fde.fd          = socket_get_fd(socket_ctx);
+       fde.fd          = socket_get_fd(sock);
        fde.flags       = EVENT_FD_READ;
-       fde.private     = srv_sock;
-       fde.handler     = model_ops->accept_connection;
-
-       ZERO_STRUCTP(srv_sock);
-       srv_sock->service       = service;
-       srv_sock->socket        = socket_ctx;
-       srv_sock->event.ctx     = service->srv_ctx->events;
-       srv_sock->event.fde     = event_add_fd(srv_sock->event.ctx, &fde);
-       if (!srv_sock->event.fde) {
-               DEBUG(0,("event_add_fd(srv_sock->event.ctx, &fde) failed\n"));
-               socket_destroy(socket_ctx);
+       fde.private     = stream_socket;
+       fde.handler     = server_accept_handler;
+
+       stream_socket->stream.ops       = stream_ops;
+       stream_socket->service          = service;
+       stream_socket->socket           = sock;
+       stream_socket->event.ctx        = service->server->event.ctx;
+       stream_socket->event.fde        = event_add_fd(stream_socket->event.ctx, &fde);
+       if (!stream_socket->event.fde) {
+               DEBUG(0,("event_add_fd(stream_socket->event.ctx, &fde) failed\n"));
+               socket_destroy(sock);
                return NULL;
        }
 
-       DLIST_ADD(service->socket_list, srv_sock);
+       talloc_steal(stream_socket, sock);
 
-       return srv_sock;
+       if (stream_socket->stream.ops->socket_init) {
+               stream_socket->stream.ops->socket_init(stream_socket);
+       }
+
+       return stream_socket;
 }
 
 /*
   destructor that handles necessary event context changes
  */
-static int server_destructor(void *ptr)
+static int server_connection_destructor(void *ptr)
 {
        struct server_connection *conn = ptr;
 
-       if (conn->service) {
-               conn->service->ops->close_connection(conn, "shutdown");
-       }
-
-       socket_destroy(conn->socket);
+       if (conn->stream_socket && 
+           conn->stream_socket->stream.ops->close_connection) {
+               /* don't remove this! the stream service needs to free it's data
+                * before we destroy the server_connection
+                */
+               conn->stream_socket->stream.ops->close_connection(conn, "shutdown");
+        }
 
        if (conn->event.fde) {
                event_remove_fd(conn->event.ctx, conn->event.fde);
@@ -201,13 +203,11 @@ static int server_destructor(void *ptr)
                conn->event.idle = NULL;
        }
 
-       DLIST_REMOVE(conn->server_socket->connection_list, conn);
-
        return 0;
 }
 
 struct server_connection *server_setup_connection(struct event_context *ev, 
-                                                 struct server_socket *server_socket, 
+                                                 struct server_stream_socket *stream_socket, 
                                                  struct socket_context *sock, 
                                                  struct timeval t,
                                                  servid_t server_id)
@@ -216,7 +216,7 @@ struct server_connection *server_setup_connection(struct event_context *ev,
        struct timed_event idle;
        struct server_connection *srv_conn;
 
-       srv_conn = talloc_p(server_socket, struct server_connection);
+       srv_conn = talloc_p(stream_socket, struct server_connection);
        if (!srv_conn) {
                DEBUG(0,("talloc_p(mem_ctx, struct server_connection) failed\n"));
                return NULL;
@@ -238,20 +238,19 @@ struct server_connection *server_setup_connection(struct event_context *ev,
        srv_conn->event.idle            = &idle;
        srv_conn->event.idle_time       = timeval_set(SERVER_DEFAULT_IDLE_TIME, 0);
 
-       srv_conn->server_socket         = server_socket;
-       srv_conn->service               = server_socket->service;
+       srv_conn->stream_socket         = stream_socket;
        srv_conn->socket                = sock;
-       srv_conn->server_id             = server_id;
+       srv_conn->connection.id         = server_id;
 
        /* create a server context and add it to out event
           handling */
-       server_socket->service->ops->accept_connection(srv_conn);
+       stream_socket->stream.ops->accept_connection(srv_conn);
 
        /* accpect_connection() of the service may changed idle.next_event */
        srv_conn->event.fde     = event_add_fd(ev,&fde);
        srv_conn->event.idle    = event_add_timed(ev,&idle);
 
-       talloc_set_destructor(srv_conn, server_destructor);
+       talloc_set_destructor(srv_conn, server_connection_destructor);
 
        if (!socket_check_access(sock, "smbd", lp_hostsallow(-1), lp_hostsdeny(-1))) {
                server_terminate_connection(srv_conn, "denied by access rules");
@@ -259,7 +258,11 @@ struct server_connection *server_setup_connection(struct event_context *ev,
        }
 
        /* setup to receive internal messages on this connection */
-       srv_conn->messaging_ctx = messaging_init(srv_conn, srv_conn->server_id, ev);
+       srv_conn->messaging.ctx = messaging_init(srv_conn, srv_conn->connection.id, ev);
+       if (!srv_conn->messaging.ctx) {
+               server_terminate_connection(srv_conn, "messaging_init() failed");
+               return NULL;
+       }
 
        return srv_conn;
 }
@@ -270,7 +273,15 @@ struct server_connection *server_setup_connection(struct event_context *ev,
 void server_terminate_connection(struct server_connection *srv_conn, const char *reason)
 {
        DEBUG(2,("server_terminate_connection\n"));
-       srv_conn->service->model_ops->terminate_connection(srv_conn, reason);
+       srv_conn->stream_socket->service->server->model.ops->terminate_connection(srv_conn, reason);
+}
+
+void server_accept_handler(struct event_context *ev, struct fd_event *fde, 
+                      struct timeval t, uint16_t flags)
+{
+       struct server_stream_socket *stream_socket = fde->private;
+
+       stream_socket->service->server->model.ops->accept_connection(ev, fde, t, flags);
 }
 
 void server_io_handler(struct event_context *ev, struct fd_event *fde, 
@@ -281,12 +292,12 @@ void server_io_handler(struct event_context *ev, struct fd_event *fde,
        conn->event.idle->next_event = timeval_sum(&t,  &conn->event.idle_time);
 
        if (flags & EVENT_FD_WRITE) {
-               conn->service->ops->send_handler(conn, t, flags);
+               conn->stream_socket->stream.ops->send_handler(conn, t, flags);
                return;
        }
 
        if (flags & EVENT_FD_READ) {
-               conn->service->ops->recv_handler(conn, t, flags);
+               conn->stream_socket->stream.ops->recv_handler(conn, t, flags);
        }
 
 }
@@ -296,13 +307,34 @@ void server_idle_handler(struct event_context *ev, struct timed_event *idle,
 {
        struct server_connection *conn = idle->private;
 
-       conn->event.idle->next_event = timeval_sum(&t, &conn->event.idle_time);
-
        /* Not all services provide an idle handler */
-       if (conn->service->ops->idle_handler) {
-               conn->service->ops->idle_handler(conn, t);
+       if (conn->stream_socket->stream.ops->idle_handler) {
+               conn->event.idle->next_event = timeval_sum(&t, &conn->event.idle_time);
+               conn->stream_socket->stream.ops->idle_handler(conn, t);
        }
 }
+
+void server_terminate_task(struct server_task *task, const char *reason)
+{
+       task->service->server->model.ops->terminate_task(task, reason);
+       return;
+}
+
+void server_run_task(struct server_service *service, const struct server_task_ops *ops)
+{
+       struct server_task *task;
+
+       task = talloc_zero(service, struct server_task);
+       if (!task) {
+               return;
+       }
+       task->service           = service;
+       task->task.ops          = ops;
+
+       service->server->model.ops->create_task(task);
+       return;
+}
+
 /*
   return the operations structure for a named backend of the specified type
 */
@@ -325,25 +357,6 @@ NTSTATUS register_server_service_ops(const void *_ops)
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-/*
-  close all listening sockets. This is called by process models that fork, to 
-  ensure that the listen sockets from the parent are closed
-*/
-void service_close_listening_sockets(struct server_context *srv_ctx)
-{
-       struct server_service *svc;
-       for (svc=srv_ctx->service_list;svc;svc=svc->next) {
-               struct server_socket *sock;
-               for (sock=svc->socket_list;sock;sock=sock->next) {
-                       event_remove_fd(sock->event.ctx, sock->event.fde);
-                       sock->event.fde = NULL;
-                       socket_destroy(sock->socket);
-                       sock->socket = NULL;
-               }
-       }
-}
-
-
 /*
   cleanup temporary files. This is the new alternative to
   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
index 20bf6e9b8fd6a9f4cde5b338242b6e461f7af46b..d5335b1cef68309d2bf3ed6faacfb6e3311fdfe9 100644 (file)
@@ -42,7 +42,17 @@ struct server_service_ops {
        const char *name;
 
        /* called at startup when the server_service is selected */
-       void (*service_init)(struct server_service *service, const struct model_ops *ops);
+       void (*service_init)(struct server_service *service);   
+};
+
+struct server_stream_socket;
+
+struct server_stream_ops {
+       /* the name of the server_service */
+       const char *name;
+
+       /* called at startup when the server_service is selected */
+       void (*socket_init)(struct server_stream_socket *socket);
 
        /* function to accept new connection */
        void (*accept_connection)(struct server_connection *);
@@ -56,16 +66,16 @@ struct server_service_ops {
 
        /* function to close a connection */
        void (*close_connection)(struct server_connection *, const char *reason);
-
-       /* function to exit server */
-       void (*service_exit)(struct server_service *srv_ctx, const char *reason);       
 };
 
 struct socket_context;
 
-struct server_socket {
-       struct server_socket *next,*prev;
-       void *private_data;
+struct server_stream_socket {
+       struct server_stream_socket *next,*prev;
+       struct {
+               const struct server_stream_ops *ops;
+               void *private_data;
+       } stream;
 
        struct {
                struct event_context *ctx;
@@ -75,20 +85,16 @@ struct server_socket {
        struct socket_context *socket;
 
        struct server_service *service;
-
-       struct server_connection *connection_list;
 };
 
 struct server_service {
        struct server_service *next,*prev;
-       void *private_data;
-       const struct server_service_ops *ops;
-
-       const struct model_ops *model_ops;
-
-       struct server_socket *socket_list;
+       struct {
+               const struct server_service_ops *ops;
+               void *private_data;
+       } service;
 
-       struct server_context *srv_ctx;
+       struct server_context *server;
 };
 
 /* the concept of whether two operations are on the same server
@@ -106,7 +112,10 @@ typedef uint32_t servid_t;
 
 struct server_connection {
        struct server_connection *next,*prev;
-       void *private_data;
+       struct {
+               void *private_data;
+               servid_t id;
+       } connection;
 
        struct {
                struct event_context *ctx;
@@ -115,15 +124,42 @@ struct server_connection {
                struct timeval idle_time;
        } event;
 
-       servid_t server_id;
-
        struct socket_context *socket;
 
-       struct server_socket *server_socket;
+       struct server_stream_socket *stream_socket;
 
-       struct server_service *service;
+       struct {
+               struct messaging_context *ctx;
+       } messaging;
+};
+
+struct server_task;
+
+struct server_task_ops {
+       /* the name of the server_task */
+       const char *name;
+
+       /* called at startup when the server_task is selected */
+       void (*task_init)(struct server_task *task);
+};
+
+struct server_task {
+       struct server_task *next,*prev;
+       struct {
+               const struct server_task_ops *ops;
+               void *private_data;
+               servid_t id;
+       } task;
+
+       struct {
+               struct event_context *ctx;
+       } event;
+
+       struct {
+               struct messaging_context *ctx;
+       } messaging;
 
-       struct messaging_context *messaging_ctx;
+       struct server_service *service;
 };
 
 #endif /* _SERVER_SERVICE_H */