mpm_cache.c File Reference

Cache messages and attachments so we can reduce WAN traffic. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/modules/mpm_cache.h"

Functions

static NTSTATUS cache_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
 
static void cache_dump_stream_stat (struct mpm_stream *stream)
 
static NTSTATUS cache_exec_sync_cmd (struct mpm_stream *stream)
 
static uint32_t cache_find_call_request_index (uint8_t opnum, struct EcDoRpc_MAPI_REQ *mapi_req)
 
static NTSTATUS cache_init (struct dcesrv_context *dce_ctx)
 
static NTSTATUS cache_pull (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
 
static NTSTATUS cache_pull_OpenAttach (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_pull_OpenMessage (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct OpenMessage_req request)
 
static NTSTATUS cache_pull_OpenStream (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_pull_Release (struct dcesrv_call_state *dce_call, struct EcDoRpc *EcDoRpc, uint32_t handle_idx)
 
static NTSTATUS cache_push (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
 
static NTSTATUS cache_push_OpenAttach (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_push_OpenMessage (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_push_OpenStream (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_push_ReadStream (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
 
static NTSTATUS cache_unbind (struct server_id server_id, uint32_t context_id)
 
NTSTATUS samba_init_module (void)
 

Variables

types h stat h wait h struct
mpm_cache
mpm = NULL
 

Detailed Description

Cache messages and attachments so we can reduce WAN traffic.

Function Documentation

static NTSTATUS cache_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy mapiproxy 
)
static

Dispatch function.

This function avoids calling dcerpc_ndr_request - understand forwarding client request to remove server - when the client is reading a message/attachment stream available in the cache.

This function can also be used to loop over dcerpc_ndr_request and perform a read-ahead operation.

Parameters
dce_callthe session context
mem_ctxthe memory context
rpointer on EcDoRpc operation
mapiproxypointer to a mapiproxy structure controlling mapiproxy behavior.
Returns
NT_STATUS_OK

References mapiproxy::ahead, mpm_stream::ahead, cache_dump_stream_stat(), mpm_stream::cached, mpm_stream::handle, mpm_cache_stream_read(), mpm_cache_stream_reset(), mpm_cache_stream_write(), MPM_LOCATION, mpm_session_cmp(), mpm_stream::next, mapiproxy::norelay, mpm_stream::offset, mpm_stream::session, mpm_cache::streams, and mpm_stream::StreamSize.

Referenced by samba_init_module().

static void cache_dump_stream_stat ( struct mpm_stream stream)
static

Dump time statistic between OpenStream and Release

This function monitors the effective time required to open, read and close a stream.

Parameters
streamthe mpm_stream entry

References mpm_stream::ahead, mpm_stream::attachment, mpm_attachment::AttachmentID, mpm_stream::cached, mpm_message::FolderId, mpm_attachment::message, mpm_stream::message, mpm_message::MessageId, and mpm_stream::tv_start.

Referenced by cache_dispatch(), and cache_push_ReadStream().

static NTSTATUS cache_exec_sync_cmd ( struct mpm_stream stream)
static
  1. close the existing FILE *
  2. build complete file path
  3. replace FILE arguments with complete file path
  4. call execve
  5. stat the sync'd file
  6. open the stream again
  7. mark the file as cached
Parameters
streampointer on the mpm_stream entry

References mpm_stream::cached, mpm_stream::filename, mpm_cache_stream_close(), mpm_cache_stream_open(), mpm_stream::StreamSize, and mpm_cache::sync_cmd.

Referenced by cache_push_ReadStream().

static uint32_t cache_find_call_request_index ( uint8_t  opnum,
struct EcDoRpc_MAPI_REQ *  mapi_req 
)
static

Find the position of the given MAPI call in a serialized MAPI request.

If the request includes a Release call, then request and replies indexes for other calls will mismatch.

Parameters
opnumThe MAPI opnum to seek
mapi_reqPointer to the MAPI request calls array
Returns
On success, returns the call position, otherwise -1.

Referenced by cache_push().

static NTSTATUS cache_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the cache module and retrieve configuration from smb.conf

Possible smb.conf parameters: mpm_cache:database

Parameters
dce_ctxthe session context
Returns
NT_STATUS_OK on success otherwise NT_STATUS_INVALID_PARAMETER, NT_STATUS_NO_MEMORY

References mpm_cache::ahead, mpm_cache::attachments, mpm_cache::dbpath, mpm_cache::ldb_ctx, mpm_cache::messages, mpm_cache_ldb_createdb(), MPM_DB, MPM_ERROR, MPM_NAME, mpm_cache::streams, mpm_cache::sync, mpm_cache::sync_cmd, and mpm_cache::sync_min.

Referenced by samba_init_module().

static NTSTATUS cache_pull ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

Analyze EcDoRpc MAPI requests

This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly.

Parameters
dce_callthe session context
mem_ctxthe memory context
rgeneric pointer on EcDoRpc operation
Returns
NT_STATUS_OK

References cache_pull_OpenAttach(), cache_pull_OpenMessage(), cache_pull_OpenStream(), and cache_pull_Release().

Referenced by samba_init_module().

static NTSTATUS cache_pull_OpenAttach ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenAttach requests and register an attachment in the mpm_messages list.

This is the first step for attachment registration. This function first ensures the attachment is not already registered, otherwise delete it. It next creates the attachment entry in the global mpm_message structure.

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
mapi_reqreference to the OpenAttach EcDoRpc_MAPI_REQ entry
EcDoRpcpointer to the EcDoRpc operation
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY

References mpm_attachment::AttachmentID, mpm_cache::attachments, mpm_session::context_id, mpm_message::FolderId, mpm_message::handle, mpm_attachment::handle, mpm_attachment::message, mpm_message::MessageId, mpm_cache::messages, MPM_LOCATION, mpm_session_cmp(), mpm_session_init(), mpm_message::next, mpm_attachment::next, mpm_attachment::parent_handle, mpm_session::server_id, mpm_message::session, and mpm_attachment::session.

Referenced by cache_pull().

static NTSTATUS cache_pull_OpenMessage ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct OpenMessage_req  request 
)
static

Monitor OpenMessage requests and register a message in the mpm_messages list.

This is the first step for message registration: set Folder ID and Message ID set the handle to 0xFFFFFFFF Insert the message to the list

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
requestreference to the OpenMessage request
Returns
NT_STATUS_OK on success

References mpm_message::FolderId, mpm_message::handle, mpm_message::MessageId, mpm_cache::messages, mpm_session_cmp(), mpm_session_init(), mpm_message::next, and mpm_message::session.

Referenced by cache_pull().

static NTSTATUS cache_pull_OpenStream ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenStream requests and register a stream in the mpm_streams list.

We are only interested in monitoring streams related to attachments or messages. This is the first step for stream registration:

Look whether this stream inherits from a message or attachment Fill the stream element according to previous statement Add it to the mpm_stream list

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
mapi_reqreference to the OpenStream MAPI request
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY

References mpm_stream::ahead, mpm_cache::ahead, mpm_stream::attachment, mpm_cache::attachments, mpm_stream::cached, mpm_session::context_id, mpm_stream::filename, mpm_message::FolderId, mpm_message::handle, mpm_attachment::handle, mpm_stream::handle, mpm_attachment::message, mpm_stream::message, mpm_message::MessageId, mpm_cache::messages, MPM_LOCATION, mpm_session_cmp(), mpm_session_init(), mpm_message::next, mpm_attachment::next, mpm_stream::parent_handle, mpm_stream::PropertyTag, mpm_session::server_id, mpm_message::session, mpm_attachment::session, mpm_stream::session, mpm_cache::streams, mpm_stream::StreamSize, and mpm_stream::tv_start.

Referenced by cache_pull().

static NTSTATUS cache_pull_Release ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc *  EcDoRpc,
uint32_t  handle_idx 
)
static

Track down Release calls and update the mpm_cache global list - removing associated entries.

This function recursively remove child entries whenever necessary.

Parameters
dce_callpointer to the session context
EcDoRpcpointer to the EcDoRpc operation
handle_idxthe handle to track down
Returns
NT_STATUS_OK

References mpm_attachment::AttachmentID, mpm_cache::attachments, mpm_session::context_id, mpm_stream::filename, mpm_message::FolderId, mpm_message::handle, mpm_attachment::handle, mpm_stream::handle, mpm_message::MessageId, mpm_cache::messages, mpm_cache_stream_close(), MPM_LOCATION, mpm_session_cmp(), mpm_session_release(), mpm_message::next, mpm_attachment::next, mpm_stream::next, mpm_attachment::parent_handle, mpm_stream::parent_handle, mpm_session::server_id, mpm_message::session, mpm_attachment::session, mpm_stream::session, and mpm_cache::streams.

Referenced by cache_pull().

static NTSTATUS cache_push ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

Analyze EcDoRpc MAPI responses

This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly.

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
rgeneric pointer on EcDoRpc operation
Returns
NT_STATUS_OK

References cache_find_call_request_index(), cache_push_OpenAttach(), cache_push_OpenMessage(), cache_push_OpenStream(), and cache_push_ReadStream().

Referenced by samba_init_module().

static NTSTATUS cache_push_OpenAttach ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenAttach replies and store OpenAttach MAPI handle.

This is the second step for attachment registration:

Seek for a given parent_handle/attachmentID in the mpm_attachments list.

if a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle parameter for the element and commit this attachment in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the element.

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenAttach request entry
mapi_replreference to the OpenAttach MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_attachment::AttachmentID, mpm_cache::attachments, mpm_session::context_id, mpm_attachment::handle, mpm_cache::ldb_ctx, mpm_cache_ldb_add_attachment(), MPM_LOCATION, mpm_session_cmp(), mpm_attachment::next, mpm_attachment::parent_handle, mpm_session::server_id, and mpm_attachment::session.

Referenced by cache_push().

static NTSTATUS cache_push_OpenMessage ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenMessage replies and store OpenMessage MAPI handle.

This is the second step for message registration:

Seek for a given FolderId/MessageId in the mpm_message list

If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field for the element and commit this message in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the record

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenMessage MAPI request entry
mapi_replreference to the OpenMessage MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_session::context_id, mpm_message::FolderId, mpm_message::handle, mpm_cache::ldb_ctx, mpm_message::MessageId, mpm_cache::messages, mpm_cache_ldb_add_message(), MPM_LOCATION, mpm_session_cmp(), mpm_message::next, mpm_session::server_id, and mpm_message::session.

Referenced by cache_push().

static NTSTATUS cache_push_OpenStream ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenStream replies and store the OpenStream MAPI handle.

This is the second step for stream registration:

Seek the parent_handle/PropertyTag couple in the mpm_streams list.

If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field and StreamSize parameters for the element and commit this stream in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the element.

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenStream MAPI request entry
mapi_replreference to the OpenStream MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_session::context_id, mpm_stream::handle, mpm_cache::ldb_ctx, mpm_cache_ldb_add_stream(), MPM_LOCATION, mpm_session_cmp(), mpm_stream::next, mpm_stream::parent_handle, mpm_stream::PropertyTag, mpm_session::server_id, mpm_stream::session, mpm_cache::streams, and mpm_stream::StreamSize.

Referenced by cache_push().

static NTSTATUS cache_push_ReadStream ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor ReadStream replies.

This function writes ReadStream data received from remote server and associated to messages or attachments to the opened associated file. This function only writes data if the file is not already cached, otherwise it just returns.

Parameters
dce_callpointer to the session context
mapi_reqreference to the ReadStream MAPI request
mapi_replreference to the ReadStream MAPI reply
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK
See Also
cache_dispatch

References cache_dump_stream_stat(), cache_exec_sync_cmd(), mpm_stream::cached, mpm_session::context_id, mpm_stream::fp, mpm_stream::handle, mpm_cache_stream_write(), MPM_LOCATION, mpm_session_cmp(), mpm_stream::next, mpm_stream::offset, mpm_session::server_id, mpm_stream::session, mpm_cache::streams, mpm_stream::StreamSize, mpm_cache::sync, and mpm_cache::sync_min.

Referenced by cache_push().

Variable Documentation


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/