poser
A C framework for POsix SERvices
|
A socket connection. More...
#include <poser/core/connection.h>
Public Member Functions | |
PSC_Connection * | PSC_Connection_createTcpClient (const PSC_TcpClientOpts *opts) |
Create a connection as a TCP client. | |
int | PSC_Connection_createTcpClientAsync (const PSC_TcpClientOpts *opts, void *receiver, PSC_ClientCreatedHandler callback) |
Create a connection as a TCP client asynchronously. | |
PSC_Connection * | PSC_Connection_createUnixClient (const PSC_UnixClientOpts *opts) |
Create a connection as a UNIX socket client. | |
PSC_Event * | PSC_Connection_connected (PSC_Connection *self) |
Connection successfully connected. | |
PSC_Event * | PSC_Connection_closed (PSC_Connection *self) |
Connection closed. | |
PSC_Event * | PSC_Connection_dataReceived (PSC_Connection *self) |
Data received. | |
PSC_Event * | PSC_Connection_dataSent (PSC_Connection *self) |
Data sent. | |
PSC_Event * | PSC_Connection_nameResolved (PSC_Connection *self) |
Remote name resolved. | |
const char * | PSC_Connection_remoteAddr (const PSC_Connection *self) |
The remote address. | |
const char * | PSC_Connection_remoteHost (const PSC_Connection *self) |
The remote hostname. | |
int | PSC_Connection_remotePort (const PSC_Connection *self) |
The remote port. | |
int | PSC_Connection_receiveBinary (PSC_Connection *self, size_t expected) |
Configure for receiving binary data. | |
void | PSC_Connection_receiveText (PSC_Connection *self, PSC_MessageEndLocator locator) |
Configure for receiving text. | |
void | PSC_Connection_receiveLine (PSC_Connection *self) |
Configure for receiving lines. | |
int | PSC_Connection_sendAsync (PSC_Connection *self, const uint8_t *buf, size_t sz, void *id) |
Send data to the peer. | |
int | PSC_Connection_sendTextAsync (PSC_Connection *self, const char *text, void *id) |
Send text to the peer. | |
void | PSC_Connection_pause (PSC_Connection *self) |
Pause receiving data. | |
int | PSC_Connection_resume (PSC_Connection *self) |
Resume receiving data. | |
int | PSC_Connection_confirmDataReceived (PSC_Connection *self) |
Confirm receiving data is completed. | |
void | PSC_Connection_close (PSC_Connection *self, int blacklist) |
Close connection. | |
void | PSC_Connection_setData (PSC_Connection *self, void *data, void(*deleter)(void *)) |
Attach a data object. | |
void * | PSC_Connection_data (const PSC_Connection *self) |
Retreive attached data object. | |
A socket connection.
This class offers reading from and writing to a socket (TCP or local UNIX) and retreiving basic peer information.
A connection cannot be created directly. It's either created as a client, or obtained from a PSC_Server when a client connected there.
There's no destructor either, a connection destroys itself after being closed and having done the necessary cleanup. Note that it automatically closes on any errors, so if you need to know about it, you should listen on the PSC_Connection_closed() event.
void PSC_Connection_close | ( | PSC_Connection * | self, |
int | blacklist | ||
) |
Close connection.
This initiates closing the connection. If TLS is enabled, the TLS shutdown is initiated immediately, and completed asynchronously if necessary.
A closed event is fired (either immediately or after completing the TLS shutdown) and then, the connection is scheduled for deletion after all events were handled, which will also close the socket.
self | the PSC_Connection |
blacklist | (0) or (1): also blacklist the socket address, so it won't be reused immediately, use when the peer behaved erroneously |
PSC_Event * PSC_Connection_closed | ( | PSC_Connection * | self | ) |
Connection closed.
This event fires when the connection was closed, either by calling PSC_Connection_close(), or because the peer closed it, or because of any error.
If the connection was fully connected before, it passes itself as the event arguments. Otherwise, the event args will be NULL. That way, it's possible to know whether there was an error during establishing the connection.
self | the PSC_Connection |
int PSC_Connection_confirmDataReceived | ( | PSC_Connection * | self | ) |
Confirm receiving data is completed.
This reactivates reading from the connection after it was paused by calling PSC_EADataReceived_markHandling() in a data received event handler, to signal the buffer is still being processed. For every event handler setting the mark, a call to this function is needed to actually resume receiving.
Note this is independent from the PSC_Connection_pause() mechanism. A PSC_Connection will only receive data when it isn't paused and no PSC_EADataReceived is marked as being handled.
self | the PSC_Connection |
PSC_Event * PSC_Connection_connected | ( | PSC_Connection * | self | ) |
Connection successfully connected.
This event fires as soon as a connection is fully connected and therefore ready to communicate. Note this never fires on connections obtained from a PSC_Server, they are already connected.
self | the PSC_Connection |
PSC_Connection * PSC_Connection_createTcpClient | ( | const PSC_TcpClientOpts * | opts | ) |
Create a connection as a TCP client.
The created connection will be in a "connecting" state. To know when it is successfully connected, you must listen on the PSC_Connection_connected() event.
opts | TCP client options |
int PSC_Connection_createTcpClientAsync | ( | const PSC_TcpClientOpts * | opts, |
void * | receiver, | ||
PSC_ClientCreatedHandler | callback | ||
) |
Create a connection as a TCP client asynchronously.
To create a TCP client, it can be necessary to resolve a remote hostname, and/or to read a client certificate to use with TLS. Using this function, these things are done in background, so it is recommended to use this function from within a running service. The connection is created when all required information is present, and passed to the callback provided here.
Note that the created connection will still be in a "connecting" state, so you still have to listen on the PSC_Connection_connected() event to know when it is successfully connected.
opts | TCP client options |
receiver | the object to receive the callback (or NULL) |
callback | the callback function |
PSC_Connection * PSC_Connection_createUnixClient | ( | const PSC_UnixClientOpts * | opts | ) |
Create a connection as a UNIX socket client.
The created connection will be in a "connecting" state. To know when it is successfully connected, you must listen on the PSC_Connection_connected() event.
opts | UNIX client options |
void * PSC_Connection_data | ( | const PSC_Connection * | self | ) |
Retreive attached data object.
Get data that was attached with PSC_Connection_setData().
self | the PSC_Connection |
PSC_Event * PSC_Connection_dataReceived | ( | PSC_Connection * | self | ) |
Data received.
This event fires whenever there was new data received on the socket. It passes a PSC_EADataReceived instance as event arguments, from which you can access a buffer and its size.
You can also mark the buffer as being handled. This will stop receiving more data (which would overwrite the buffer) until you explicitly call PSC_Connection_confirmDataReceived().
self | the PSC_Connection |
PSC_Event * PSC_Connection_dataSent | ( | PSC_Connection * | self | ) |
Data sent.
This event fires when data passed to PSC_Connection_sendAsync() was sent. It only fires when an "id" object was passed with the data. This object is passed back via event args, so you can identify which write completed.
self | the PSC_Connection |
PSC_Event * PSC_Connection_nameResolved | ( | PSC_Connection * | self | ) |
Remote name resolved.
This event fires as soon as the name of the peer was successfully resolved.
self | the PSC_Connection |
void PSC_Connection_pause | ( | PSC_Connection * | self | ) |
Pause receiving data.
Stop receiving further data unless PSC_Connection_resume() is called. For each call to PSC_Connection_pause(), a corresponding call to PSC_Connection_resume() is necessary.
self | the PSC_Connection |
int PSC_Connection_receiveBinary | ( | PSC_Connection * | self, |
size_t | expected | ||
) |
Configure for receiving binary data.
This is the default mode of a newly created PSC_Connection.
The optional expected argument can be used when the protocol requires the peer to send an exact amount of bytes next. When it is set to a non-zero value, the next PSC_Connection_dataReceived() event will have exactly this size. It must not be larger than the size of the receive buffer configured for the PSC_Connection, otherwise this call will fail.
When expected is set to 0 (the default), any amount of data received will instantly be passed in the next PSC_Connection_dataReceived() event.
self | the PSC_Connection |
expected | how many bytes to receive next, or 0 for any amount |
void PSC_Connection_receiveLine | ( | PSC_Connection * | self | ) |
Configure for receiving lines.
Use this when implementing a typical line-based protocol.
When configured for receiving lines, the PSC_EADataReceived event argument will contain a pointer to a nul-terminated C string. The string will end when either an actual nul-byte was enocuntered in the received data, or one of "\r\n", "\r" or "\n" was found (which will be included), or the receiving buffer was full.
self | the PSC_Connection |
void PSC_Connection_receiveText | ( | PSC_Connection * | self, |
PSC_MessageEndLocator | locator | ||
) |
Configure for receiving text.
Use this when implementing a text-based protocol.
When configured for receiving text, the PSC_EADataReceived event argument will contain a pointer to a nul-terminated C string. The string will end when either an actual nul-byte was encountered in the received data, or the given locator found an end position, or the receiving buffer was full.
self | the PSC_Connection |
locator | callback function to find the end of the message |
const char * PSC_Connection_remoteAddr | ( | const PSC_Connection * | self | ) |
The remote address.
The address of the peer. For TCP connections, an IPv4 or IPv6 address. For local UNIX connections, the name of the socket.
self | the PSC_Connection |
const char * PSC_Connection_remoteHost | ( | const PSC_Connection * | self | ) |
The remote hostname.
The hostname of the peer. For local UNIX sockets, or if not resolved yet, or if resolving is disabled: NULL.
self | the PSC_Connection |
int PSC_Connection_remotePort | ( | const PSC_Connection * | self | ) |
The remote port.
For local UNIX sockets, this returns 0.
self | the PSC_Connection |
int PSC_Connection_resume | ( | PSC_Connection * | self | ) |
Resume receiving data.
Allow receiving of new data again after calling PSC_Connection_pause(). Must be called the same number of times to actually resume receiving.
self | the PSC_Connection |
int PSC_Connection_sendAsync | ( | PSC_Connection * | self, |
const uint8_t * | buf, | ||
size_t | sz, | ||
void * | id | ||
) |
Send data to the peer.
The data passed is scheduled for sending and sent as soon as the socket is ready for sending. If an id is given, a PSC_Connection_dataSent() event fires as soon as the data was actually sent, passing back the id as the event args.
WARNING: The data you pass is not (immediately) copied, instead a pointer to it is saved to copy data into the sending buffer as soon as the socket is ready for sending and there's enough room.
As a consequence, do not pass a pointer to an object with automatic storage duration! (IOW, do not pass a pointer to some local variable). Doing so will not work and, in the worst case, crash your service.
Instead, either use a static buffer (static storage duration or a member of your own dynamically allocated object) or dynamically allocate a buffer that you can destroy again from a PSC_Connection_dataSent() handler.
self | the PSC_Connection |
buf | pointer to the data |
sz | size of the data |
id | optional identifier object |
int PSC_Connection_sendTextAsync | ( | PSC_Connection * | self, |
const char * | text, | ||
void * | id | ||
) |
Send text to the peer.
For text-based protocols, this is a convenient alternative to PSC_Connection_sendAsync(), taking a nul-terminated C string instead of a binary buffer and a size. Otherwise, it works exactly the same, so here as well, be careful not to pass a pointer to an object with automatic storage duration!
self | the PSC_Connection |
text | the text to send |
id | optional identifier object |
void PSC_Connection_setData | ( | PSC_Connection * | self, |
void * | data, | ||
void(*)(void *) | deleter | ||
) |
Attach a data object.
Attach some custom data to the connection.
self | the PSC_Connection |
data | the data to attach |
deleter | if not NULL, called on the data when the connection is destroyed or some different data is attached |