Protocol Plug-in Programming Guide: Protocol Level Plug-in API Reference
Previous Next Contents Index


Chapter 3 Protocol Level Plug-in API Reference

This chapter is a reference to Protocol Level Plug-in API functions, data structures, macros, and result codes.

The chapter has the following sections:

The Protocol Level Plug-in API is defined in the protplug.h header file. You can see this file in HTML format or download the file.


Functions
The Protocol Level Plug-in API includes the following functions. Table 3.1 lists API functions and any data structures on which they operate.

Table 3.1 Protocol Level Plug-in API functions
Function

Description

Structure

PPModule_Init
Entry point for a protocol plug-in module library.
ProtPlugSystem
PPModule_Exit
Performs resource cleanup in a protocol level plug-in.

PPModule_NewProtPlug
Creates a new ProtPlug, the session analogue of a PPModule.
PPSession
ProtPlug

ProtPlug_ProcessLine
Called when a line has been received in the protocol.
ProtPlug
ProtPlug_Delete
Frees memory associated with a protocol plug-in session.
ProtPlug

PPModule_Init
Initialization entry point for a protocol plug-in module library.

Syntax
#include <protplug.h>
int PPModule_Init(
ProtPlugSystem *pSys);
Parameters
The function has the following parameter:
pSys
Pointer to structure that represents the protocol level plug-in library.

Returns
Description
This function is the initialization entry point for a protocol plug-in module library (PPModule). It is called once at server start-up.

The ProtPlugSystem structure is passed to this function at start-up time by the smtpd. This makes it possible for PPModule_Init to perform tasks such as setting global pointers to system information, announcing the plug-in the server log, initializing configuration lists, initializing buffers for response strings the plug-in will use, finding out the server instance directory, and initializing any ProtPlugSystem function pointers that the plug-in uses.

This function is called in a multi-threaded context, and so must be thread safe.

If PPModule_Init fails, PPModule_Exit is not called.

For more information, see "Using Protocol Level Plug-in Functions."

See Also
ProtPlugSystem, PPModule_Exit

[Functions]

PPModule_Exit
Performs resource cleanup in a protocol level plug-in.

Syntax
#include <protplug.h> 
void PPModule_Exit(void);
Description
This function is intended for resource cleanup in a a protocol level plug-in (PPModule). It is called after all ProtPlug structures have been deleted, before the server exits.

For more information, see "Using Protocol Level Plug-in Functions."

See Also
PPModule_Init

[Functions]

PPModule_NewProtPlug
Creates a new instance of a protocol level plug-in.

Syntax
#include <protplug.h>
ProtPlug *PPModule_NewProtPlug(PPSession *ps);
Parameters
The function has the following parameters:
ps
Pointer to session-specific data and functions from the server. Opaque handle used by the plug-in to call session-specific functions. Can be stored as one of the elements in the ProtPlug structure.

Returns
Description
This function creates a new instance of a protocol level plug-in (ProtPlug structure), the session analogue of a PPModule. You write the function according to the requirements of your plug-in. When the server calls this function, it expects that a ProtPlug structure will be returned to it.

This function is called in a multi-threaded context, and so must be thread safe.

For more information, see "Using Protocol Level Plug-in Functions."

See Also
ProtPlug, PPSession

[Functions]

ProtPlug_ProcessLine
Called when a line has been received in the protocol.

Syntax
#include <protplug.h>
int ProtPlug_ProcessLine(
ProtPlug *ppp,
char *pszLine,
char **ppszResp);
Parameters
The function has the following parameters:
ppp
Pointer to the protocol level plug-in session pointer returned by PPModule_NewProtPlug.
pszLine
Pointer to the line to be processed; can be an SMTP command or the body of the message; null-terminated and includes "\r\n". When the connection is established, the MTA calls the plug-in and passes a null pointer to this parameter, which displays a protocol banner. The plug-in should respond with PP_SKIP.
The memory pointed to by this parameter is owned by the server and may not be modified or freed by the ProtPlug.
ppszResp
Pointer to a pointer to the (input/output) desired response, the text to be sent to the remote server; null-terminated and includes "\r\n". For possible responses, see Returns in this section.
If null, the server assumes that the line has not been processed and that the server should handle the line itself.
The memory pointed to by this parameter belongs to the ProtPlug and need only be valid until the next call to ProtPlug_ProcessLine or ProtPlug_Delete, the server will not modify or free it.

Returns
The function returns the following codes:
PP_DONE
The command was handled, and is over. No more lines remain.
PP_MORE
The command was handled, but has not finished. More lines needed.
PP_SKIP
The command was ignored. Subsequent lines for the command should not be sent to this ProtPlug.
PP_CLOSE
The command was handled. The session (connection) should be closed after sending the response (if any).

Description
This function is called on a ProtPlug when a new line is received in the protocol.

The pszLine parameter represents the line that comes from the remote server, either an SMTP command such as HELO or RCPT TO, or the body of the message. When the plug-in is called by the MTA, it passes a double pointer to the next plug-in to in the stack.

If the plug-in decides not to handle a command, or if it determines that the server should process a different pszLine, it should call the PPSESSION_DEFERLINE access macro on its session.

This function is called in a multi-threaded context, and so must be thread safe.

For information, see "Using Protocol Level Plug-in Functions."

See Also
PPSESSION_DEFERLINE, ProtPlug

[Functions]

ProtPlug_Delete
Frees memory associated with a protocol level plug-in session.

Syntax
#include <protplug.h>
void ProtPlug_Delete(
ProtPlug *ppp);
Parameters
The function has the following parameter:
ppp
Pointer to the session to delete.

Description
This function terminates the session of the protocol level plug-in. It must free all memory associated with the ProtPlug. Use this function to remove anything plug-in-specific that was created during the plug-in session.

For more information, see "Using Protocol Level Plug-in Functions."

See Also
ProtPlug

[Functions]


Return Values for Functions
Protocol Level Plug-in API functions that return pointers to structures or to strings return null on error. Functions that return an integer return 0 on success and a negative value on error.

All input parameters are validity checked for memory corruption and return an appropriate error if necessary.


Access Macros
The Protocol Level Plug-in API includes the following access macros.

Table 3.2 Protocol Level Plug-in API macros
Macro
Description
PPSESSION_DEFERLINE
Used to call the DeferLine function.
PPSESSION_GETPROPERTY
Used to call the GetProperty function.

Warning. You must always use these access macros to call the functions defined in this structure. §

PPSESSION_DEFERLINE
Used to call the DeferLine function.

Syntax
#include <protplug.h>
PPSESSION_DEFERLINE(p,l,r)
((
PPSessionActions *)(p))->DeferLine((p),(l),(r))
Parameters
The macro has the following parameters:
p
The plug-in session.
l
Returns the current line.
r
Returns a pointer to a response, either PP_DONE, PP_MORE, PP_SKIP, or PP_CLOSE. For a description of these responses, see Table 2.2.

Description
This macro calls the DeferLine function, which passes control to the next plug-in the chain and allows the calling plug-in to see and act on the response.

The DeferLine function is defined as a function pointer within the PPSessionActions structure. Always use this macro to call this function; do not use the PPSessionActions function pointer.

This is one of two macros defined in the Plug-in API. The other is PPSESSION_GETPROPERTY, which calls the GetProperty function.

For more information, see "Using Macros."

See Also
PPSessionActions, PPSESSION_GETPROPERTY

[Access Macros]

PPSESSION_GETPROPERTY
Used to call the GetProperty function.

Syntax
#include <protplug.h>
PPSESSION_GETPROPERTY(p,k,d)
(((
PPSessionActions *)(p))->GetProperty((p),(k),(d)))
Parameters
The macro has the following parameters:
p
The plug-in session.
k
The keys you can pass to the PPSESSION_GETPROPERTY macro to get session-specific properties from the server. For a list of keys you can use, see Table 3.3.
d
Default. Should always be null.

Description
This macro calls the GetProperty function, which retrieves information about the current session, such as client IP-address, authentication state, and other properties.

The GetProperty function is defined as a function pointer within the PPSessionActions structure. Always use this macro to call this function; do not use the PPSessionActions function pointer.

The k parameter represents the keys you can pass to the GETPROPERTY macro to get the values for properties of the current session from the server. Table 3.3 shows the keys you can use.

Table 3.3 Keys for the pszKey parameter of the GETPROPERTY macro
pszKey Value
Description
TLS
yes/no, in TLS
ESMTP
yes/no, received good EHLO signal
BadCert
yes/no, SSLclientcert bad
ReceivedLines
int, "Received" lines
SizeOfHeader
int
SizeOfBody
int
PeerName
peer name (if available)
PeerIP
peer ip (dot-quad)
HostName
server hostname
HeloDomain
domain given in EHLO
SenderAuthed
yes/no
AuthSender
authenticated sender
Sender
from
Recipients
comma-separated recipient list
BadCommands
int, number of bad commands so far in the current session

The d parameter is a default parameter that should always be null. It is reserved for future expansion.

This is one of two macros defined in the Plug-in API. The other is PPSESSION_DEFERLINE, which calls the DeferLine function.

For more information, see "Using Macros" and "The PPSessionActions Structure."

See Also
PPSessionActions, PPSESSION_DEFERLINE

[Access Macros]


Data Structures
This section lists the data structures used in Protocol Level Plug-in API functions.

Table 3.4 Protocol Level Plug-in API data structures
Structure
Description
PPMutex
Represents the PPMutex synchronization object.
PPSession
Represents the handle to the current server session.
PPSessionActions
Represents available actions for the plug-in session.
ProtPlugSystem
Represents the protocol level plug-in library.
ProtPlug
Represents the protocol level plug-in session.

PPMutex
Represents the mutex synchronization object.

Syntax
#include <protplug.h>
typedef struct PPMutexStruct PPMutex;
Description
The PPMutex (mutual exclusion log) structure provides the mutex synchronization object.

Due to the fact that Messaging Server 4.1 is multithreaded, you must ensure that your plug-in code is thread-safe. If you use global data, you should use the PPMutex object. Before a plug-in function changes global data, it has to obtain the mutex object. Any other threads of operation have to wait until the mutex is released. Because only one thread can obtain the mutex at one time, only one function or operation can change the global variable.

Plug-ins that do not use global data, such as the Anti-Relay plug-in, do not need to use a mutex object.

You handle this structure through the functions provided in the ProtPlugSystem structure, which is created by the PPModule_Init function. These functions are summarized in Table 3.5.

Table 3.5 ProtPlugSystem structure PPMutex functions
Function Pointer
Description
PPMutex *(*PPMutex_New)(void);
Creates a PPMutex object.
void (*PPMutex_Lock)(PPMutex *pm);
Locks a PPMutex object (pm).
void (*PPMutex_Unlock)(PPMutex *pm);
Unlocks a PPMutex object (pm).
void (*PPMutex_Delete)(PPMutex *pm);
Deletes a PPMutex object (pm).

When the MTA starts and calls PPModule_Init, it passes in a ProtPlugSystem structure. If the plug-in uses global data, you implement the PPMutex_New function to create a PPMutex. Then you must use PPMutex_Lock to lock the PPMutex object and PPMutex_Unlock to unlock it. If you create a PPMutex, you must delete it with the PPMutex_Delete function. For more information, see "Multithreading, Global Data, and Mutex."

You can create as many PPMutex objects you want, but be aware that there can be complications. For example, a deadlock can occur when two processes, which may be using different levels of PPMutex, try to change the same data at the same time. In this case, both are blocked.

Warning. Before you write a protocol level plug-in, you should have a thorough understanding of global data and multithreaded programming. §

See Also
ProtPlugSystem

[Data Structures]

PPSession
Represents an opaque handle that identifies the current session.

Syntax
#include <protplug.h>
typedef struct PPSessionStruct PPSession;
Description
The PPSession structure represents an opaque handle that identifies the current session for various API functions, such as GetProperty.

The PPSession structure contains system specific functions, in contrast with the ProtPlug structure, which is a user-defined structure that you can create with your own data. You can store the PPSession information that is passed through the PPModule_NewProtPlug function in the ProtPlug structure.

For more information, see "Working with Plug-in Structures."

This example uses the PPSession structure to pass session-persistent data to the plug-in each time it is called:

struct ProtPlugSystem {
int iSomeCount; /* counter used by the plug-in */
PPSession *pMySession; /* ptr to current session handle */
char *pszMyPeerAddress; /* buffer for the client address */
char *pszResp; /* response buffer */
};
See Also
ProtPlug, PPSessionActions

[Data Structures]

PPSessionActions
Represents available actions for the plug-in session.

Syntax
#include <protplug.h>
typedef struct PPSessionActionsStruct
{
int (*DeferLine)
(
PPSession *ps, char *pszLine, char **ppszResp);
char *(*GetProperty)
(PPSession *ps, char *pszKey, char *pszDefault);
} PPSessionActions;
Fields
The structure has the following fields:
int (*DeferLine)
PPSession *ps,
char *pszLine,
char **ppszResp);
Passes control to the next plug-in the chain; allows the calling plug-in to see and act on the response. Parameters:
char *(*GetProperty)
(PPSession *ps,
char *pszKey,
char *pszDefault);
Retrieves session-specific properties such as client IP-address, authentication state, and others. Parameters:

Description
The PPSessionActions structure contains function pointers that determine the action the plug-in should take.

When you call GetProperty, you should always pass null to the pszDefault parameter. This parameter is reserved for future expansion.

Warning. To access the functions in this structure, you must use only the access macros PPSESSION_DEFERLINE and PPSESSION_GETPROPERTY. §

For more information, see "The PPSessionActions Structure" and "Using Macros."

See Also
PPSession, PPSESSION_DEFERLINE, PPSESSION_GETPROPERTY

[Data Structures]

ProtPlugSystem
Represents the protocol level plug-in library.

Syntax
#include <protplug.h>
typedef struct ProtPlugSystemStruct
{
void *(*PPRealloc)(void *pOld, int nSize);
/* all memory comes from here */
PPMutex *(*PPMutex_New)(void);
void (*PPMutex_Lock)(PPMutex *pm);
void (*PPMutex_Unlock)(PPMutex *pm);
void (*PPMutex_Delete)(PPMutex *pm);
char *(*PPGetIni)(char *pszKey, char *pszDefault,
char *pszResult, int nResultSize);
void (*PPLogPrintf)(char *pszFormat,...);
struct in_addr (*PPGetHostByName)(char *pszName);
char *(*PPGetHostByAddr)(struct in_addr ina,
char *pBuf, int nBufSize);
} ProtPlugSystem;
Fields
The structure has the following fields:
char *(*PPRealloc)
(char *pOld, int nSize);
Allocates, reallocates, and frees all memory used by the plug-in.
PPMutex *(*PPMutex_New)(void);
Creates a mutex synchronization object.
void (*PPMutex_Lock)(PPMutex *pm);
Locks a mutex object (pm).
void (*PPMutex_Unlock)(PPMutex *pm);
Unlocks a mutex object (pm).
void (*PPMutex_Delete)(PPMutex *pm);
Deletes a mutex object (pm).
char *(*PPGetIni)
(char *pszKey,
char *pszDefault,
char *pszResult,
int nResultSize);
Allows access to basic server configuration information stored in Directory Server or local config.db. Parameters:
char *(*PPLogPrintf)
(char *pszFormat,...);
Writes to the SMTP server log. Parameters:
struct in_addr (*PPGetHostByName)
(char *pszName);
Provides basic name resolution functionality. Returns the IP address based on the display name. Parameters:
char *(*PPGetHostByAddr)
(struct in_addr ina,
char *pBuf,
int nBufSize);
Provides basic name resolution functionality. Returns the actual name of the host in the pBuf parameter. Parameters:

Description
The ProtPlugSystem structure represents the protocol level plug-in library. It is passed to the PPModule_Init function, which initializes the plug-in at start-up time, from the smtpd.

The function pointers defined in ProtPlugSystem provide services to the plug-in. For details about function parameters, see their entries in the Fields table in this section.

For more information, see "Working with Plug-in Structures."

See Also
PPModule_Init, PPMutex, ProtPlug

[Data Structures]

ProtPlug
Represents the protocol level plug-in session.

Syntax
#include <protplug.h>
typedef struct ProtPlugStruct ProtPlug;
Description
The ProtPlug structure represents the session analogue of a protocol plug-in (PPModule). This is a user-defined structure that you can create with your own data. In the definition of ProtPlug, the ProtPlugStruct structure represents a structure that you define according to the requirements of your plug-in.

The ProtPlug structure is created by the PPModule_NewProtPlug function. You can store session information (represented by the PPSession structure) passed through PPModule_NewProtPlug as one of the elements in the ProtPlug structure.

See Also
PPModule_NewProtPlug, ProtPlugSystem, PPSession

[Data Structures]


Plug-in Result Codes
The protocol level plug-in's main function should return one of these codes to Messaging Server.

Table 3.6 Protocol Level plug-in result codes
Code
No.
Description
PP_OK
0
The command was handled successfully. Messaging Server should continue to process the resulting messages.
PP_SKIP
1
Do not call the ProcessLine function again until this command has finished. This speeds up the SMTP DATA command.
PP_KILL
2
Terminate the connection after sending the response (if any).

 

© Copyright 1999 Netscape Communications Corp., a subsidiary of America Online, Inc. All rights reserved.