mirror of https://github.com/sipwise/heartbeat.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
6.1 KiB
205 lines
6.1 KiB
/*
|
|
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <ipctransient.h>
|
|
|
|
gboolean transient_server_callback(IPC_Channel *client, gpointer user_data);
|
|
gboolean transient_server_connect(IPC_Channel *client_channel, gpointer user_data);
|
|
int init_server_ipc_comms(const char *child,
|
|
gboolean (*channel_client_connect)(IPC_Channel *newclient, gpointer user_data),
|
|
void (*channel_input_destroy)(gpointer user_data),
|
|
gboolean usenormalpoll);
|
|
|
|
int
|
|
main(int argc, char ** argv)
|
|
{
|
|
int iteration = 0;
|
|
GMainLoop* mainloop = NULL;
|
|
|
|
trans_getargs(argc, argv);
|
|
|
|
cl_log_set_entity(procname);
|
|
cl_log_enable_stderr(TRUE);
|
|
|
|
init_server_ipc_comms("echo", transient_server_connect, default_ipctest_input_destroy, FALSE);
|
|
|
|
/* wait for the reply by creating a mainloop and running it until
|
|
* the callbacks are invoked...
|
|
*/
|
|
mainloop = g_main_new(FALSE);
|
|
|
|
cl_log(LOG_INFO, "#--#--#--# Echo Server %d is active...", iteration);
|
|
g_main_run(mainloop);
|
|
cl_log(LOG_INFO, "#--#--#--# Echo Server %d is stopped...", iteration);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int
|
|
init_server_ipc_comms(const char *child,
|
|
gboolean (*channel_client_connect)(IPC_Channel *newclient, gpointer user_data),
|
|
void (*channel_input_destroy)(gpointer user_data),
|
|
gboolean usenormalpoll)
|
|
{
|
|
/* the clients wait channel is the other source of events.
|
|
* This source delivers the clients connection events.
|
|
* listen to this source at a relatively lower priority.
|
|
*/
|
|
mode_t mask;
|
|
IPC_WaitConnection *wait_ch;
|
|
GHashTable * attrs;
|
|
int local_sock_len = 2; /* 2 = '/' + '\0' */
|
|
char *commpath = NULL;
|
|
static char path[] = IPC_PATH_ATTR;
|
|
|
|
local_sock_len += strlen(child);
|
|
local_sock_len += strlen(commdir);
|
|
|
|
commpath = (char*)malloc(sizeof(char)*local_sock_len);
|
|
if (commpath == NULL){
|
|
cl_log(LOG_ERR, "%s: allocating memory failed", __FUNCTION__);
|
|
exit(1);
|
|
}
|
|
snprintf(commpath, local_sock_len, "%s/%s", commdir, child);
|
|
commpath[local_sock_len - 1] = '\0';
|
|
|
|
attrs = g_hash_table_new(g_str_hash,g_str_equal);
|
|
g_hash_table_insert(attrs, path, commpath);
|
|
|
|
mask = umask(0);
|
|
wait_ch = ipc_wait_conn_constructor(IPC_ANYTYPE, attrs);
|
|
if (wait_ch == NULL){
|
|
cl_perror("[Server] Can't create wait channel of type %s", IPC_ANYTYPE);
|
|
exit(1);
|
|
}
|
|
mask = umask(mask);
|
|
g_hash_table_destroy(attrs);
|
|
|
|
G_main_add_IPC_WaitConnection(G_PRIORITY_LOW,
|
|
wait_ch,
|
|
NULL,
|
|
FALSE,
|
|
channel_client_connect,
|
|
wait_ch, /* user data passed to ?? */
|
|
channel_input_destroy);
|
|
|
|
cl_log(LOG_INFO, "[Server] Listening on: %s", commpath);
|
|
|
|
/* if (!usenormalpoll) { */
|
|
/* g_main_set_poll_func(cl_glibpoll); */
|
|
/* ipc_set_pollfunc(cl_poll); */
|
|
/* } */
|
|
return 0;
|
|
}
|
|
|
|
gboolean
|
|
transient_server_callback(IPC_Channel *client, gpointer user_data)
|
|
{
|
|
int lpc = 0;
|
|
IPC_Message *msg = NULL;
|
|
char *buffer = NULL;
|
|
IPC_Message *reply = NULL;
|
|
int llpc = 0;
|
|
|
|
cl_log(LOG_DEBUG, "channel: %p", client);
|
|
|
|
cl_log(LOG_DEBUG, "Client status %d (disconnect=%d)", client->ch_status, IPC_DISCONNECT);
|
|
|
|
while(client->ops->is_message_pending(client)) {
|
|
if (client->ch_status == IPC_DISCONNECT) {
|
|
/* The message which was pending for us is that
|
|
* the IPC status is now IPC_DISCONNECT */
|
|
break;
|
|
}
|
|
if(client->ops->recv(client, &msg) != IPC_OK) {
|
|
cl_perror("[Server] Receive failure");
|
|
return FALSE;
|
|
}
|
|
|
|
if (msg != NULL) {
|
|
lpc++;
|
|
buffer = (char*)g_malloc(msg->msg_len+1);
|
|
memcpy(buffer,msg->msg_body, msg->msg_len);
|
|
buffer[msg->msg_len] = '\0';
|
|
cl_log(LOG_DEBUG, "[Server] Got xml [text=%s]", buffer);
|
|
|
|
reply = create_simple_message(strdup(buffer), client);
|
|
if (!reply) {
|
|
cl_log(LOG_ERR, "[Server] Could allocate reply msg.");
|
|
return FALSE;
|
|
}
|
|
|
|
llpc = 0;
|
|
while(llpc++ < MAX_IPC_FAIL && client->ops->send(client, reply) == IPC_FAIL) {
|
|
cl_log(LOG_WARNING, "[Server] ipc channel blocked");
|
|
cl_shortsleep();
|
|
}
|
|
|
|
if(lpc == MAX_IPC_FAIL) {
|
|
cl_log(LOG_ERR, "[Server] Could not send IPC, message. Channel is dead.");
|
|
free(reply);
|
|
return FALSE;
|
|
}
|
|
|
|
cl_log(LOG_DEBUG, "[Server] Sent reply");
|
|
msg->msg_done(msg);
|
|
} else {
|
|
cl_log(LOG_ERR, "[Server] No message this time");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
cl_log(LOG_DEBUG, "[Server] Processed %d messages", lpc);
|
|
|
|
cl_log(LOG_DEBUG, "[Server] Client status %d", client->ch_status);
|
|
if(client->ch_status != IPC_CONNECT) {
|
|
cl_log(LOG_INFO, "[Server] Server received HUP from child");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
gboolean
|
|
transient_server_connect(IPC_Channel *client_channel, gpointer user_data)
|
|
{
|
|
/* assign the client to be something, or put in a hashtable */
|
|
cl_log(LOG_DEBUG, "A client tried to connect... and there was much rejoicing.");
|
|
|
|
if(client_channel == NULL) {
|
|
cl_log(LOG_ERR, "[Server] Channel was NULL");
|
|
} else if(client_channel->ch_status == IPC_DISCONNECT) {
|
|
cl_log(LOG_ERR, "[Server] Channel was disconnected");
|
|
} else {
|
|
cl_log(LOG_DEBUG, "[Server] Client is %s %p", client_channel == NULL?"NULL":"valid", client_channel);
|
|
cl_log(LOG_DEBUG, "[Server] Client status %d (disconnect=%d)", client_channel->ch_status, IPC_DISCONNECT);
|
|
|
|
cl_log(LOG_DEBUG, "[Server] Adding IPC Channel to main thread.");
|
|
G_main_add_IPC_Channel(G_PRIORITY_LOW,
|
|
client_channel,
|
|
FALSE,
|
|
transient_server_callback,
|
|
NULL,
|
|
default_ipctest_input_destroy);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|