Blame src/mw_channel.h

Packit Service 37472d
Packit Service 37472d
/*
Packit Service 37472d
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit Service 37472d
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit Service 37472d
  
Packit Service 37472d
  This library is free software; you can redistribute it and/or
Packit Service 37472d
  modify it under the terms of the GNU Library General Public
Packit Service 37472d
  License as published by the Free Software Foundation; either
Packit Service 37472d
  version 2 of the License, or (at your option) any later version.
Packit Service 37472d
  
Packit Service 37472d
  This library is distributed in the hope that it will be useful,
Packit Service 37472d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 37472d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 37472d
  Library General Public License for more details.
Packit Service 37472d
  
Packit Service 37472d
  You should have received a copy of the GNU Library General Public
Packit Service 37472d
  License along with this library; if not, write to the Free
Packit Service 37472d
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit Service 37472d
*/
Packit Service 37472d
Packit Service 37472d
#ifndef _MW_CHANNEL_H
Packit Service 37472d
#define _MW_CHANNEL_H
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @file mw_channel.h
Packit Service 37472d
    
Packit Service 37472d
Life-cycle of an outgoing channel:
Packit Service 37472d
Packit Service 37472d
1: mwChannel_new is called. If there is a channel in the outgoing
Packit Service 37472d
collection in state NEW, then it is returned. Otherwise, a channel
Packit Service 37472d
is allocated, assigned a unique outgoing id, marked as NEW, and
Packit Service 37472d
returned.
Packit Service 37472d
Packit Service 37472d
2: channel is set to INIT status (effectively earmarking it as in-
Packit Service 37472d
use).  fields on the channel can then be set as necessary to
Packit Service 37472d
prepare it for creation.
Packit Service 37472d
Packit Service 37472d
3: mwChannel_create is called. The channel is marked to WAIT status
Packit Service 37472d
and a message is sent to the server. The channel is also marked as
Packit Service 37472d
inactive as of that moment.
Packit Service 37472d
Packit Service 37472d
4: the channel is accepted (step 5) or rejected (step 7)
Packit Service 37472d
Packit Service 37472d
5: an accept message is received from the server, and the channel
Packit Service 37472d
is marked as OPEN, and the inactive mark is removed. And messages
Packit Service 37472d
in the in or out queues for that channel are processed. The channel
Packit Service 37472d
is now ready to be used.
Packit Service 37472d
Packit Service 37472d
6: data is sent and received over the channel
Packit Service 37472d
Packit Service 37472d
7: the channel is closed either by receipt of a close message or by
Packit Service 37472d
local action. If by local action, then a close message is sent to
Packit Service 37472d
the server.  The channel is cleaned up, its queues dumped, and it
Packit Service 37472d
is set to NEW status to await re-use.
Packit Service 37472d
Packit Service 37472d
Life-cycle of an incoming channel:
Packit Service 37472d
Packit Service 37472d
1: a channel create message is received. A channel is allocated and
Packit Service 37472d
given an id matching the message. It is placed in status WAIT, and
Packit Service 37472d
marked as inactive as of that moment. The service matching that
Packit Service 37472d
channel is alerted of the incoming creation request.
Packit Service 37472d
Packit Service 37472d
2: the service can either accept (step 3) or reject (step 5) the
Packit Service 37472d
channel
Packit Service 37472d
Packit Service 37472d
3: mwChannel_accept is called. The channel is marked as OPEN, and
Packit Service 37472d
an accept message is sent to the server. And messages in the in or
Packit Service 37472d
out queues for that channel are processed. The channel is now ready
Packit Service 37472d
to be used.
Packit Service 37472d
Packit Service 37472d
4: data is sent and received over the channel
Packit Service 37472d
Packit Service 37472d
5: The channel is closed either by receipt of a close message or by
Packit Service 37472d
local action. If by local action, then a close message is sent to
Packit Service 37472d
the server.  The channel is cleaned up, its queues dumped, and it
Packit Service 37472d
is deallocated. */
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#include <time.h>
Packit Service 37472d
#include "mw_common.h"
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#ifdef __cplusplus
Packit Service 37472d
extern "C" {
Packit Service 37472d
#endif
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/* place-holders */
Packit Service 37472d
struct mwCipherInstance;
Packit Service 37472d
struct mwMsgChannelAccept;
Packit Service 37472d
struct mwMsgChannelCreate;
Packit Service 37472d
struct mwMsgChannelDestroy;
Packit Service 37472d
struct mwMsgChannelSend;
Packit Service 37472d
struct mwService;
Packit Service 37472d
struct mwSession;
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @struct mwChannel
Packit Service 37472d
    Represents a channel to a service */
Packit Service 37472d
struct mwChannel;
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @struct mwChannelSet
Packit Service 37472d
    Collection of channels */
Packit Service 37472d
struct mwChannelSet;
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** special ID indicating the master channel */
Packit Service 37472d
#define MW_MASTER_CHANNEL_ID  0x00000000
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** non-zero if a channel id appears to be that of an outgoing channel */
Packit Service 37472d
#define mwChannel_idIsOutgoing(id) \
Packit Service 37472d
  (! (0x80000000 & (id)))
Packit Service 37472d
Packit Service 37472d
/** non-zero if a channel id appears to be that of an incoming channel */
Packit Service 37472d
#define mwChannel_idIsIncoming(id) \
Packit Service 37472d
  (! mwChannel_idIsOutgoing(id))
Packit Service 37472d
Packit Service 37472d
/** non-zero if a channel appears to be an outgoing channel */
Packit Service 37472d
#define mwChannel_isOutgoing(chan) \
Packit Service 37472d
  mwChannel_idIsOutgoing(mwChannel_getId(chan))
Packit Service 37472d
Packit Service 37472d
/** non-zero if a channel appears to be an incoming channel */
Packit Service 37472d
#define mwChannel_isIncoming(chan) \
Packit Service 37472d
  mwChannel_idIsIncoming(mwChannel_getId(chan))
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** channel status */
Packit Service 37472d
enum mwChannelState {
Packit Service 37472d
  mwChannel_NEW,      /**< channel is newly allocated, in the pool */
Packit Service 37472d
  mwChannel_INIT,     /**< channel is being prepared, out of the pool */
Packit Service 37472d
  mwChannel_WAIT,     /**< channel is waiting for accept */
Packit Service 37472d
  mwChannel_OPEN,     /**< channel is accepted and open */
Packit Service 37472d
  mwChannel_DESTROY,  /**< channel is being destroyed */
Packit Service 37472d
  mwChannel_ERROR,    /**< channel is being destroyed due to error */
Packit Service 37472d
  mwChannel_UNKNOWN,  /**< unknown state, or error determining state */
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#define mwChannel_isState(chan, state) \
Packit Service 37472d
  (mwChannel_getState(chan) == (state))
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** channel statistic fields.
Packit Service 37472d
    @see mwChannel_getStatistic */
Packit Service 37472d
enum mwChannelStatField {
Packit Service 37472d
  mwChannelStat_MSG_SENT,      /**< total send-on-chan messages sent */
Packit Service 37472d
  mwChannelStat_MSG_RECV,      /**< total send-on-chan messages received */
Packit Service 37472d
  mwChannelStat_U_BYTES_SENT,  /**< total bytes sent, pre-encryption */
Packit Service 37472d
  mwChannelStat_U_BYTES_RECV,  /**< total bytes received, post-decryption */
Packit Service 37472d
  mwChannelStat_OPENED_AT,     /**< time when channel was opened */
Packit Service 37472d
  mwChannelStat_CLOSED_AT,     /**< time when channel was closed */
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** @enum mwEncryptPolicy
Packit Service 37472d
Packit Service 37472d
    Policy for a channel, dictating what sort of encryption should be
Packit Service 37472d
    used, if any, and when.
Packit Service 37472d
*/
Packit Service 37472d
enum mwEncryptPolicy {
Packit Service 37472d
  mwEncrypt_NONE      = 0x0000, /**< encrypt none */
Packit Service 37472d
  mwEncrypt_WHATEVER  = 0x0001, /**< encrypt whatever you want */
Packit Service 37472d
  mwEncrypt_ALL       = 0x0002, /**< encrypt all, any cipher */
Packit Service 37472d
  mwEncrypt_RC2_40    = 0x1000, /**< encrypt all, RC2/40 cipher */
Packit Service 37472d
  mwEncrypt_RC2_128   = 0x2000, /**< encrypt all, RC2/128 cipher */
Packit Service 37472d
};
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Allocate and initialize a channel set for a session */
Packit Service 37472d
struct mwChannelSet *mwChannelSet_new(struct mwSession *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Clear and deallocate a channel set. Closes, clears, and frees all
Packit Service 37472d
    contained channels. */
Packit Service 37472d
void mwChannelSet_free(struct mwChannelSet *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Create an incoming channel with the given channel id. Channel's state
Packit Service 37472d
    will be set to WAIT. Primarily for use in mw_session */
Packit Service 37472d
struct mwChannel *mwChannel_newIncoming(struct mwChannelSet *, guint32 id);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Create an outgoing channel. Its channel ID will be generated by
Packit Service 37472d
    the owning channel set. Channel's state will be set to INIT */
Packit Service 37472d
struct mwChannel *mwChannel_newOutgoing(struct mwChannelSet *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Obtain a reference to a channel by its id.
Packit Service 37472d
    @returns the channel matching chan, or NULL */
Packit Service 37472d
struct mwChannel *mwChannel_find(struct mwChannelSet *cs, guint32 chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get the ID for a channel. 0x00 indicates an error, as that is not
Packit Service 37472d
    a permissible value */
Packit Service 37472d
guint32 mwChannel_getId(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get the session for a channel. */
Packit Service 37472d
struct mwSession *mwChannel_getSession(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get the ID of the service for a channel. This may be 0x00 for NEW
Packit Service 37472d
    channels */
Packit Service 37472d
guint32 mwChannel_getServiceId(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get the service for a channel. This may be NULL for NEW
Packit Service 37472d
    channels */
Packit Service 37472d
struct mwService *mwChannel_getService(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** associate a channel with an owning service */
Packit Service 37472d
void mwChannel_setService(struct mwChannel *chan, struct mwService *srvc);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get service-specific data. This is for use by service
Packit Service 37472d
    implementations to easily associate information with the
Packit Service 37472d
    channel */
Packit Service 37472d
gpointer mwChannel_getServiceData(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** set service-specific data. This is for use by service
Packit Service 37472d
    implementations to easily associate information with the
Packit Service 37472d
    channel */
Packit Service 37472d
void mwChannel_setServiceData(struct mwChannel *chan,
Packit Service 37472d
			      gpointer data, GDestroyNotify clean);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwChannel_removeServiceData(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint32 mwChannel_getProtoType(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwChannel_setProtoType(struct mwChannel *chan, guint32 proto_type);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint32 mwChannel_getProtoVer(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwChannel_setProtoVer(struct mwChannel *chan, guint32 proto_ver);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Channel encryption policy.
Packit Service 37472d
Packit Service 37472d
    Cannot currently be set, used internally to automatically
Packit Service 37472d
    negotiate ciphers. Future revisions may allow this to be specified
Packit Service 37472d
    in a new channel to dictate channel encryption.
Packit Service 37472d
Packit Service 37472d
    @see enum mwEncryptPolicy
Packit Service 37472d
*/
Packit Service 37472d
guint16 mwChannel_getEncryptPolicy(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
guint32 mwChannel_getOptions(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
void mwChannel_setOptions(struct mwChannel *chan, guint32 options);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** User at the other end of the channel. The target user for outgoing
Packit Service 37472d
    channels, the creator for incoming channels */
Packit Service 37472d
struct mwLoginInfo *mwChannel_getUser(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** direct reference to the create addtl information for a channel */
Packit Service 37472d
struct mwOpaque *mwChannel_getAddtlCreate(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** direct reference to the accept addtl information for a channel */
Packit Service 37472d
struct mwOpaque *mwChannel_getAddtlAccept(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** automatically adds instances of all ciphers in the session to the
Packit Service 37472d
    list of supported ciphers for a channel */
Packit Service 37472d
void mwChannel_populateSupportedCipherInstances(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** add a cipher instance to a channel's list of supported
Packit Service 37472d
    ciphers. Channel must be NEW. */
Packit Service 37472d
void mwChannel_addSupportedCipherInstance(struct mwChannel *chan,
Packit Service 37472d
					  struct mwCipherInstance *ci);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** the list of supported ciphers for a channel. This list will be
Packit Service 37472d
    empty once a cipher has been selected for the channel */
Packit Service 37472d
GList *mwChannel_getSupportedCipherInstances(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** select a cipher instance for a channel. A NULL instance indicates
Packit Service 37472d
    that no encryption should be used. */
Packit Service 37472d
void mwChannel_selectCipherInstance(struct mwChannel *chan,
Packit Service 37472d
				    struct mwCipherInstance *ci);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
struct mwCipherInstance *
Packit Service 37472d
mwChannel_getCipherInstance(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** get the state of a channel  */
Packit Service 37472d
enum mwChannelState mwChannel_getState(struct mwChannel *);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** obtain the value for a statistic field as a gpointer */
Packit Service 37472d
gpointer mwChannel_getStatistic(struct mwChannel *chan,
Packit Service 37472d
				enum mwChannelStatField stat);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Formally open a channel.
Packit Service 37472d
Packit Service 37472d
    For outgoing channels: instruct the session to send a channel
Packit Service 37472d
    create message to the server, and to mark the channel (which must
Packit Service 37472d
    be in INIT status) as being in WAIT status.
Packit Service 37472d
   
Packit Service 37472d
    For incoming channels: configures the channel according to options
Packit Service 37472d
    in the channel create message. Marks the channel as being in WAIT
Packit Service 37472d
    status
Packit Service 37472d
*/
Packit Service 37472d
int mwChannel_create(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Formally accept an incoming channel. Instructs the session to send
Packit Service 37472d
    a channel accept message to the server, and to mark the channel as
Packit Service 37472d
    being OPEN. */
Packit Service 37472d
int mwChannel_accept(struct mwChannel *chan);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Destroy a channel. Sends a channel-destroy message to the server,
Packit Service 37472d
    and perform cleanup to remove the channel.
Packit Service 37472d
Packit Service 37472d
    @param chan    the channel to destroy
Packit Service 37472d
    @param reason  the reason code for closing the channel
Packit Service 37472d
    @param data    optional additional information 
Packit Service 37472d
*/
Packit Service 37472d
int mwChannel_destroy(struct mwChannel *chan, guint32 reason,
Packit Service 37472d
		      struct mwOpaque *data);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Compose a send-on-channel message, encrypt it as per the channel's
Packit Service 37472d
    specification, and send it */
Packit Service 37472d
int mwChannel_send(struct mwChannel *chan, guint32 msg_type,
Packit Service 37472d
		   struct mwOpaque *msg);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Compose a send-on-channel message, and if encrypt is TRUE, encrypt
Packit Service 37472d
    it as per the channel's specification, and send it */
Packit Service 37472d
int mwChannel_sendEncrypted(struct mwChannel *chan,
Packit Service 37472d
			    guint32 msg_type, struct mwOpaque *msg,
Packit Service 37472d
			    gboolean encrypt);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** pass a create message to a channel for handling */
Packit Service 37472d
void mwChannel_recvCreate(struct mwChannel *chan,
Packit Service 37472d
			  struct mwMsgChannelCreate *msg);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** pass an accept message to a channel for handling */
Packit Service 37472d
void mwChannel_recvAccept(struct mwChannel *chan,
Packit Service 37472d
			  struct mwMsgChannelAccept *msg);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** pass a destroy message to a channel for handling */
Packit Service 37472d
void mwChannel_recvDestroy(struct mwChannel *chan,
Packit Service 37472d
			   struct mwMsgChannelDestroy *msg);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
/** Feed data into a channel. */
Packit Service 37472d
void mwChannel_recv(struct mwChannel *chan, struct mwMsgChannelSend *msg);
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#ifdef __cplusplus
Packit Service 37472d
}
Packit Service 37472d
#endif
Packit Service 37472d
Packit Service 37472d
Packit Service 37472d
#endif /* _MW_CHANNEL_H */
Packit Service 37472d