• Welcome to Valhalla Legends Archive.
 

A Protocol Plugin System

Started by shadypalm88, April 28, 2005, 09:36 PM

Previous topic - Next topic

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:
/*
* 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 */


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.)

MyndFyre

#1
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:
What's new in the latest update?
--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:


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.

--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.

To Do:
--Define service profile-specific messages for creation, configuration, and management (message range 0x40-0x5f)
--Document messages above 0x22.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Banana fanna fo fanna


shadypalm88


Banana fanna fo fanna

Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.

iago

Quote from: Banana fanna fo fanna on May 08, 2005, 07:55 PM
Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.

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
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Banana fanna fo fanna

Quote from: iago on May 12, 2005, 09:42 PM
Quote from: Banana fanna fo fanna on May 08, 2005, 07:55 PM
Why don't you use them? They're a million zillion times better than anyone on this forum could come up with.

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

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.

Adron

Quote from: Banana fanna fo fanna on May 14, 2005, 08:21 PM
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.

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.