Valhalla Legends Forums Archive | General Programming | A Protocol Plugin System

AuthorMessageTime
shadypalm88
I'm writing a server for a messaging / chat / etc service that has presence and chat servers.  I figured it'd be easier and more convienent to write a super server of sorts, one that would load protocol plugins at runtime and manage their network connections, provide some configuration facilities, etc.  The server is being written in C.

I figured that the server could run a listener thread for each service to monitor for activity, and when a new connection or some data came in, pass it off to the first-available worker thread.  The worker thread would then call the event handlers in the plugin and let it handle the data.

This is what I'd come up with so far for the plugin interface:
[code]/*
* Chat Matrix
* Server
* Copyright (c) 2004-2005 Eric Naeseth and Richard Pianka.
*
* Plugin
* March 25, 2005
*/

#ifndef CM_PLUGIN_H_INCLUDED
#define CM_PLUGIN_H_INCLUDED

#ifndef CM_SERVER_H
#include "server.h"
#endif

#include "connection.h"

#ifndef CM_NETWORK_H
#include "network.h"
#endif

#define CM_PLUGINCALL __stdcall

/*
* Plugin functions
*/
typedef int (CM_PLUGINCALL *plugin_init)();
typedef int (CM_PLUGINCALL *plugin_connected)(cm_connection_t* connection);
typedef void (CM_PLUGINCALL *plugin_recv)(cm_connection_t* connection,
const char* data, unsigned int length);
typedef void (CM_PLUGINCALL *plugin_conerr)(cm_connection_t* connection,
int error);
typedef void (CM_PLUGINCALL *plugin_disconnected)(cm_connection_t* connection);
typedef void (CM_PLUGINCALL *plugin_unload)();

typedef struct _cmserver_plugin {
unsigned int struct_version;

plugin_init func_init;
plugin_connected func_connected;
plugin_recv func_recv;
plugin_conerr func_conerr;
plugin_disconnected func_disconnected;
plugin_unload func_unload;
} cm_plugin_t;

typedef cm_plugin_t* (CM_PLUGINCALL *plugin_getinfo)();

#endif /* CM_PLUGIN_H_INCLUDED */[/code]

When the server loads the plugin (using API appropriate to the host OS), it calls the function named plugin_getinfo that must be exported in the module.  This returns a pointer to a structure with function pointers to the rest of the plugin's functions.

But then I got to thinking how the plugin would call functions in the server app, and if the server should just pass a big struct filled with function pointers to the plugin.  But I thought that was terribly kludgy.  So, does anyone have any thoughts or suggestions on how I should structure this?  (I know I should probably add some method to get information about the plugin programatically.)
April 29, 2005, 2:36 AM
Myndfyr
If you're interested, I'm in the process of documenting a protocol that does exactly that.  It is currently incomplete, but it is located at:

http://www.jinxbot.net/rsp/

The protocol defines how the server configures chat extensions and whatnot.  However, as it is incomplete, it is still subject to change.  ;)  I wish I could tell you *how* to do it, but I can't :/

I would very much appreciate your comments.  PM me if you have any :)

This is the "Updated 4-26" list:
[u]What's new in the latest update?[/u]
--Under "General Purpose," I indicated that the protocol is suitable for both transactional and pushed interactions.
--Under "Data Types," I indicated that floating-point numbers should be formatted to strings before serialization over the network.
--Under "Protocol Messages," I removed RSP_CREATE_CONFIRM and RSP_CREATE_CONFIRM_ADMIN, and added RSP_ENUM_GROUPS, RSP_ENUM_USERS, and RSP_MANAGE_USER.
--Under RSP_PROTOCOL_VERSION, I added a technology code: 0x06, for COM/ActiveX.
--Under RSP_LOGON_CONFIRMED, I added an "Expiration Information" field and amended the rights flags field to include the following flags:

[pre]
0x01000000 PASSWORD_EXPIRES_IN_TIME – specifies that the user’s password expires at the time
given in the “Expiration Information” field, which is in fact a TIME field.  See remarks
below for more information.
0x02000000 PASSWORD_EXPIRES_IN_LOGONS – specifies that the user’s password expires
following the number of logons given in the “Expiration Information” field.  See remarks
below for more information.
0x04000000 ACCOUNT_EXPIRES_IN_TIME – specifies that the user’s account exires at the time
given in the “Expiration Information” field, which is in fact a TIME field.  See remarks
below for more information.
0x08000000 ACCOUNT_EXPIRES_IN_LOGONS – specifies that the user’s account expires following the
number of logons given in the “Expiration Information” field.  See remarks below for
more information.
*     Account and password expiration is optional on a per-server basis and may be used to enforce good security
practices or to permit service trial periods.  If any of the expiration conditions exist, the server should report
the conditions such that account expiration is reported first, and number of logons is reported first (unless a
time or password condition has already been met).  Only one of these situations should be reported at a time.
[/pre]
--Documented the RSP_ENUM_SERVICES, RSP_TRANSMIT_FILTER, RSP_PROTOCOL_VIOLATION, RSP_ACCT_CREATE, and RSP_ACCT_CREATE_ADMIN messages.
--Provided format for all messages through 0x2b.
--Provided placeholders for all currently-defined messages.

[u]To Do:[/u]
--Define service profile-specific messages for creation, configuration, and management (message range 0x40-0x5f)
--Document messages above 0x22.
April 29, 2005, 3:10 AM
St0rm.iD
irc? jabber?
May 3, 2005, 1:34 AM
shadypalm88
[quote author=Banana fanna fo fanna link=topic=11417.msg110876#msg110876 date=1115084060]
irc? jabber?
[/quote]None of the above.  It's my own protocol.
May 3, 2005, 2:06 AM
St0rm.iD
Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.
May 9, 2005, 12:55 AM
iago
[quote author=Banana fanna fo fanna link=topic=11417.msg111598#msg111598 date=1115600147]
Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.
[/quote]

I find that extremely unlikely.  They're quite good, yes, and I encourage people to use a predefined standard rather than inventing their own (better for debugging, compatibility, code read/usability, etc), but that doesn't mean that people here can't do anything close to as good as them :P
May 13, 2005, 2:42 AM
St0rm.iD
[quote author=iago link=topic=11417.msg112318#msg112318 date=1115952152]
[quote author=Banana fanna fo fanna link=topic=11417.msg111598#msg111598 date=1115600147]
Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.
[/quote]

I find that extremely unlikely. They're quite good, yes, and I encourage people to use a predefined standard rather than inventing their own (better for debugging, compatibility, code read/usability, etc), but that doesn't mean that people here can't do anything close to as good as them :P
[/quote]

I disagree. They are widespread and have copious documentation, bug testing, and security and code scruitiny. They employ far more man-hours of skilled developers than any single person or small team here could muster. Their software is more mature, popular, and actively developed, maintained, documented, and probably more solid.
May 15, 2005, 1:21 AM
Adron
[quote author=Banana fanna fo fanna link=topic=11417.msg112487#msg112487 date=1116120062]
I disagree. They are widespread and have copious documentation, bug testing, and security and code scruitiny. They employ far more man-hours of skilled developers than any single person or small team here could muster. Their software is more mature, popular, and actively developed, maintained, documented, and probably more solid.
[/quote]

They are widespread, and have many problems. There's no reason to think someone here couldn't come up with something better. Better is a very relative term btw, an IRC server protocol might not be good at all for some applications.
May 15, 2005, 2:13 AM

Search