--- /dev/null
+/*
+ * @file service.c
+ * @brief The function of l7vsd is managed.
+ * @brief Two or more service takes charge of the
+ * @brief function respectively.
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2005 NTT COMWARE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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 program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ **********************************************************************/
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <sys/time.h>
+#include "logger_wrapper.h"
+#include "l7vs_config.h"
+#include "l7vs_service.h"
+#include "l7vs_module.h"
+#include "l7vs_conn.h"
+#include "l7vs_dest.h"
+#include "l7vs_iomuxlist.h"
+#include "l7vs_lsock.h"
+#include "l7vs_sched.h"
+
+#define SERVICE_REPLICATION_MAX_NUM 32
+
+//! service list pointer
+static GList * l7vs_service_list;
+
+//! service handle
+uint32_t service_handle_base = 0;
+
+//! remove_conn list pointer
+static GList * removeconn_list;
+
+//! replication component id
+#define REP_COMP_SV "virtualservice"
+
+//! replication size
+static unsigned int rep_size_num;
+
+//! Replication data backup
+static l7vs_service_repdata * rep_mirror;
+
+//static functions
+static void l7vs_service_put_service_arg(struct l7vs_service_arg_multi *);
+
+// throughput interval
+static int throughput_interval = 0;
+
+/*!
+ * make replication data from l7vs_service structure
+ * @param[in] num unsigned int/number of array(l7vs_service_repdata)
+ * @param[out] **rep_data l7vs_service_repdata struct double-pointer
+ * @return int number currently created / -1 failure
+ */
+static int
+make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )
+{
+ unsigned int loopcnt;
+ unsigned int listcnt;
+ struct l7vs_service* sv;
+ struct l7vs_service_arg_multi* svmulti;
+
+ //argument check
+ if( 1 > num )return -1;
+ if( NULL == rep_data )return -1;
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )");
+ sprintf( debugstr, "%s num = %d", debugstr, num );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, debugstr );
+ }
+
+ loopcnt = num;
+ listcnt = g_list_length( l7vs_service_list );
+ if( 0 == listcnt )return -1;
+
+ if( loopcnt > listcnt )loopcnt = listcnt;
+ for( unsigned int i = 0; i < loopcnt; ++i ){
+ sv = (struct l7vs_service*)g_list_nth_data( l7vs_service_list, i );
+ if( NULL == sv ){
+ loopcnt = i-1;
+ break;
+ }
+ svmulti = l7vs_service_get_service_arg( sv );
+ if( NULL == svmulti )return -1;
+ rep_data[i].addr = svmulti->srv_arg.addr;
+ rep_data[i].proto = svmulti->srv_arg.proto;
+ memcpy( rep_data[i].protomod, svmulti->srv_arg.protomod, L7VS_MODNAME_LEN );
+ memcpy( rep_data[i].protomod_arg, svmulti->protomod_arg, L7VS_PROTOMOD_MAX_SERVICE_ARG );
+ //Sorry server information
+ rep_data[i].sorry_cc = svmulti->srv_arg.sorry_cc;
+ rep_data[i].sorry_addr = svmulti->srv_arg.sorry_addr;
+ rep_data[i].sorry_flag = svmulti->srv_arg.sorry_flag;
+ //QoS information
+ rep_data[i].qos_threshold_up = svmulti->srv_arg.qos_threshold_up;
+ rep_data[i].qos_threshold_down = svmulti->srv_arg.qos_threshold_down;
+
+ l7vs_service_put_service_arg( svmulti );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "rep_data[%d] dump", i);
+ l7vs_service_repdata_c_str( debugstr, &rep_data[i] );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,6, debugstr );
+ }
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )");
+ sprintf( debugstr, "%s return(list num) = %d", debugstr, loopcnt );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,7, debugstr );
+ }
+ return loopcnt;
+}
+
+/*!
+ *
+ */
+void
+set_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data, l7vs_service * srv )
+{
+ struct l7vs_lsock * lsock;
+ struct l7vs_protomod * pmod;
+ struct l7vs_service * s;
+ int ret = 0;
+
+ //argument check
+ if( 0 == num )return;
+ if( NULL == rep_data )return;
+
+ for( unsigned int i = 0; i < num; ++i ){
+ //lsock lookup
+ lsock = l7vs_lsock_table_lookup( &rep_data[i].addr, rep_data[i].proto );
+ if( (NULL == lsock) || (lsock != srv->lsock) )continue;
+ //protomod lookup
+ pmod = l7vs_protomod_lookup( rep_data[i].protomod );
+ if( (NULL == pmod) || (pmod != srv->pm) )continue;
+ //
+ s = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
+ if (s == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM, 81, "l7vs_service memory allocate error" );
+ return;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", s, sizeof(struct l7vs_service) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE, 94, debugstr );
+ }
+ s->handle = TEMP_SERVICEHANDLE;
+ ret = pmod->create( rep_data[i].protomod_arg, s->handle );
+ if( (0 != ret) || (0 != pmod->compare(s->handle, srv->handle)) ){
+ pmod->destroy(s->handle);
+ free(s);
+ continue;
+ }
+ pmod->destroy(s->handle);
+ free(s);
+ srv->sorry_cc = rep_data[i].sorry_cc;
+ //if sorry is "NULL". Make a sorry_data.
+ if( NULL == srv->sorry_dest ){
+ srv->sorry_dest = l7vs_dest_create( (struct sockaddr_in*)&rep_data[i].sorry_addr, 1 );
+ }else{
+ memcpy( (void*)&srv->sorry_dest->addr, (void*)&rep_data[i].sorry_addr, sizeof(struct sockaddr_in) );
+ srv->sorry_dest->weight = 1;
+ srv->sorry_flag = rep_data[i].sorry_flag;
+ srv->qos_threshold_up = rep_data[i].qos_threshold_up;
+ srv->qos_threshold_down = rep_data[i].qos_threshold_down;
+ }
+ break;
+ }
+}
+
+/*!
+ * l7vs_servcie_get_service_arg
+ * service arg pointer lookup.
+ * @param[in] srv l7vs_service pointer.
+ * @return l7vs_service_arg_multi pointer
+ */
+struct l7vs_service_arg_multi *
+l7vs_service_get_service_arg(struct l7vs_service *srv)
+{
+ struct l7vs_service_arg_multi *sa;
+ int ret = 0;
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,7, "argument srv is NULL");
+ return NULL;
+ }
+ if( NULL == srv->pm || NULL == srv->lsock || NULL == srv->scheduler ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,8, "Invalid argument" );
+ return NULL;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_service_arg(struct l7vs_service *srv)");
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,8, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,9, debugstr );
+ }
+
+ sa = (struct l7vs_service_arg_multi *) calloc(1, sizeof(struct l7vs_service_arg_multi));
+ if (sa == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,1, "Could not allocate memory" );
+ return NULL;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", sa, sizeof(struct l7vs_service_arg_multi) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,10, debugstr );
+ }
+
+ ret = srv->pm->service_arg(sa, srv->handle);
+ if (ret == -1) {
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", sa );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,11, debugstr );
+ }
+ free( sa );
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROTOCOL,1, "service not found" );
+ return NULL;
+ }
+
+ sa->srv_arg.len = sizeof(struct l7vs_service_arg_multi);
+ sa->srv_arg.addr = srv->lsock->addr;
+ sa->srv_arg.proto = srv->lsock->proto;
+ sa->srv_arg.persist = 0 /* XXX not yet */;
+ sa->srv_arg.backlog = 5 /* XXX not yet */;
+ strcpy(sa->srv_arg.protomod, srv->pm->modname);
+ strcpy(sa->srv_arg.schedmod, srv->scheduler->modname);
+
+ sa->srv_arg.sorry_cc = srv->sorry_cc;
+ sa->srv_arg.sorry_flag = srv->sorry_flag;
+ memcpy( &sa->srv_arg.sorry_addr, &srv->sorry_dest->addr, sizeof(struct sockaddr_in) );
+
+ sa->srv_arg.qos_threshold_up = srv->qos_threshold_up;
+ sa->srv_arg.qos_threshold_down = srv->qos_threshold_down;
+
+
+ struct timeval CurrTime;
+ gettimeofday( &CurrTime, NULL );
+ if (throughput_interval == 0) {
+ if ( parameter_is_int_exist( PARAM_COMP_L7VSD, "calc_throughput_interval" ) ) {
+ throughput_interval = parameter_get_int_value( PARAM_COMP_L7VSD, "calc_throughput_interval" );
+ }
+ if (throughput_interval == 0) {
+ throughput_interval = BPS_DEFAULT_INTERVAL;
+ }
+ }
+ unsigned long long cur_recvtime = (CurrTime.tv_sec * 1000000ULL + CurrTime.tv_usec) / throughput_interval;
+ l7vs_service_update_throughput(srv, cur_recvtime);
+ srv->throughput_to_server = srv->pre_recvsize_from_client * 1000000ULL / throughput_interval;
+ srv->throughput_to_client = srv->pre_recvsize_from_server * 1000000ULL / throughput_interval;
+
+
+ if (srv->qos_threshold_up != 0) {
+ srv->throughput_to_server >= srv->qos_threshold_up
+ ? sa->srv_arg.throughput_to_server = srv->qos_threshold_up
+ : sa->srv_arg.throughput_to_server = srv->throughput_to_server;
+ } else {
+ sa->srv_arg.throughput_to_server = srv->throughput_to_server;
+ }
+
+ if (srv->qos_threshold_down != 0) {
+ srv->throughput_to_client >= srv->qos_threshold_down
+ ? sa->srv_arg.throughput_to_client = srv->qos_threshold_down
+ : sa->srv_arg.throughput_to_client = srv->throughput_to_client;
+ } else {
+ sa->srv_arg.throughput_to_client = srv->throughput_to_client;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "return value : l7vs_service_arg_multi dump" );
+ l7vs_service_arg_multi_c_str( debugstr, sa );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,12, debugstr );
+ }
+ return sa;
+}
+
+/*!
+ * service_arg destroy function.
+ * @param[in] sa l7vs_service_arg pointer
+ */
+static void
+l7vs_service_put_service_arg(struct l7vs_service_arg_multi *sa)
+{
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_put_service_arg(struct l7vs_service_arg_multi *sa)");
+ sprintf( debugstr, "%s , sa free : address = %p", debugstr, sa );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,13, debugstr );
+ }
+ free(sa);
+}
+
+
+/*!
+ * Target real servers of sets of real servers in service are retrieved.
+ * @param[in] *srv service pointer
+ * @param[in] *sin IP and port
+ * @return l7vs_dest* real server struct pointer
+ */
+struct l7vs_dest *
+l7vs_service_lookup_dest(struct l7vs_service *srv,
+ struct sockaddr_in *sin)
+{
+ GList *l;
+ struct l7vs_dest *d, *found;
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,9, "lookup dest : argument \"srv\" is NULL" );
+ return NULL;
+ }
+ if( NULL == sin ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,10, "lookup dest : argument \"sin\" is NULL" );
+ return NULL;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_lookup_dest(struct l7vs_service *srv, struct sockaddr_in *sin)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,14, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,15, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "sin dump " );
+ switch( sin->sin_family ){
+ case AF_UNIX:
+ sprintf( debugstr, "%s socket family = AF_UNIX(PF_UNIX)", debugstr );
+ break;
+ case AF_INET:
+ sprintf( debugstr, "%s socket family = AF_INET(PF_INET)", debugstr );
+ break;
+ default:
+ sprintf( debugstr, "%s socket family = %d", debugstr, sin->sin_family );
+ }
+ sprintf( debugstr, "%s port no = %d", debugstr, ntohs( sin->sin_port ) );
+ sprintf( debugstr, "%s address = %s", debugstr, inet_ntoa( sin->sin_addr ) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,16, debugstr );
+ }
+
+ found = NULL;
+ for (l = g_list_first(srv->dest_list); l != NULL; l = g_list_next(l)) {
+ d = (struct l7vs_dest *)l->data;
+ if ((d->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && (d->addr.sin_port == sin->sin_port)) {
+ found = d;
+ break;
+ }
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "return value = %p", found );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,17, debugstr );
+ }
+
+ return found;
+}
+
+/*!
+ *
+ * @param[out] **sas l7vs_service_arg pointer list
+ * @param[out] *num pointer list count
+ * @return pointer list count
+
+ */
+int
+l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)
+{
+ GList *l;
+ struct l7vs_service *srv;
+ struct l7vs_service_arg_multi *r, *s;
+ struct l7vs_service_arg_multi **sa;
+ int i, n, len;
+
+ if( NULL == sas ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,11, "list service_arg : argument \"sas\" is NULL" );
+ return -1;
+ }
+ if( NULL == num ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,12, "list service_arg : argument \"num\" is NULL" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,18, debugstr );
+ }
+
+ n = g_list_length(l7vs_service_list);
+ if (n == 0) {
+ *sas = NULL;
+ *num = 0;
+ return 0;
+ }
+
+ sa = (struct l7vs_service_arg_multi **)calloc(n, sizeof(*sa));
+ if (sa == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,2, "list service_arg : Could not allocate memory" );
+ return -1;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", sa, sizeof(struct l7vs_service_arg_multi) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,19, debugstr );
+ }
+
+ len = 0;
+ l = g_list_first(l7vs_service_list);
+ for (i = 0; i < n; i++) {
+ srv = (struct l7vs_service *)l->data;
+ sa[i] = l7vs_service_get_service_arg(srv);
+ if (sa[i] == NULL) {
+ for (i-- ; i >= 0; i--) {
+ l7vs_service_put_service_arg(sa[i]);
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", sa );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,20, debugstr );
+ }
+ free(sa);
+ return -1;
+ }
+ len += sa[i]->srv_arg.len;
+ l = g_list_next(l);
+ }
+
+ r = (struct l7vs_service_arg_multi *)malloc(len);
+ if (r == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,3, "list service_arg : Could not allocate memory" );
+ return -1;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %d", r, len );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,21, debugstr );
+ }
+
+ s = r;
+ for (i = 0; i < n; i++) {
+ memcpy(s, sa[i], sa[i]->srv_arg.len);
+ s = (struct l7vs_service_arg_multi *)((uint8_t *)s + sa[i]->srv_arg.len);
+ l7vs_service_put_service_arg(sa[i]);
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", sa );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,22, debugstr );
+ }
+ free(sa);
+ *sas = r;
+ *num = n;
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)" );
+ sprintf( debugstr, "%s return : len = %d , sas = %p , num = %d", debugstr, len, sas, *num );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,23, debugstr );
+ }
+
+ return len;
+}
+
+/*!
+ * get l7vs_dest_arg lists
+ * @param[in] *srv service pointer
+ * @param[out] **das l7vs_dest_arg pointer list
+ * @return pointer list count
+ */
+int
+l7vs_service_list_dest_arg(struct l7vs_service *srv,
+ struct l7vs_dest_arg **das)
+{
+ GList *l;
+ struct l7vs_dest *d;
+ struct l7vs_dest_arg *darg;
+ int i, num;
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,13, "list dest_arg : argument \"srv\" is NULL" );
+ return -1;
+ }
+ if( NULL == das ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,14, "list dest_arg : argument \"das\" is NULL" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_list_dest_arg(struct l7vs_service *srv, struct l7vs_dest_arg **das)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,24, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,25, debugstr );
+ }
+
+ num = g_list_length(srv->dest_list);
+ if (num == 0) {
+ *das = NULL;
+ return num;
+ }
+
+ darg = (struct l7vs_dest_arg *)malloc(num * sizeof(*darg));
+ if (darg == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,4, "Could not allocate memory" );
+ return -1;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", darg, ( num * sizeof(*darg) ) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,26, debugstr );
+ }
+
+ i = 0;
+ for (l = g_list_first(srv->dest_list); l != NULL; l = g_list_next(l)) {
+ d = (struct l7vs_dest *)l->data;
+ l7vs_dest_to_arg(d, &darg[i]);
+ i++;
+ }
+
+ *das = darg;
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_list_dest_arg(struct l7vs_service *srv, struct l7vs_dest_arg **das)" );
+ sprintf( debugstr, "%s return : num = %d , **darg = %p", debugstr, num, das );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,27, debugstr );
+ }
+
+ return num;
+}
+
+/*!
+ * create service instance. and set service value.
+ * @param[in] *arg l7vs_service_arg pointer
+ * @param[out] *err error code
+ * @return l7vs_service pointer
+ */
+struct l7vs_service *
+l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)
+{
+ struct l7vs_protomod *pmod;
+ struct l7vs_scheduler *sched;
+ struct l7vs_service *srv, *sref;
+ struct l7vs_lsock *lsock;
+ struct l7vs_dest *sorry_dest; //! sorry-server destination
+// struct l7vs_service_repdata * service_replicationdata;
+
+ int ret = 0;
+ GList *l;
+
+ if( NULL == arg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,15, "Could not create service : argument \"arg\" is NULL" );
+ return NULL;
+ }
+ if( NULL == err ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,16, "Could not create service : argument \"err\" is NULL" );
+ return NULL;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,28, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ l7vs_service_arg_multi_c_str( debugstr, arg );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,29, debugstr );
+ }
+
+ *err = 0;
+
+ /* max service guard */
+ if( g_list_length( l7vs_service_list ) >= MAX_SERVICES ){
+ LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,4, "l7vsd max service is %d, new virtual service can't create.", MAX_SERVICES );
+ *err = L7VS_CONFIG_ERR_MAXVS_EXISTS;
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE )) {
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,30, "function l7vs_service_create( struct l7vs_service_arg_multi* arg, int *err ) return : NULL (failure virtual service max limit" );
+ }
+ return NULL;
+ }
+
+ lsock = l7vs_lsock_get(&arg->srv_arg.addr, arg->srv_arg.proto, arg->srv_arg.backlog);
+ if (lsock == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,1, "Could not create listen socket" );
+ *err = L7VS_CONFIG_ERR_NOSOCK;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_lsock_get)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,31, debugstr );
+ }
+ return NULL;
+ }
+
+ pmod = l7vs_protomod_get(arg->srv_arg.protomod);
+ if (pmod == NULL) {
+ l7vs_lsock_put(lsock);
+ *err = L7VS_CONFIG_ERR_NOMEM;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_protomod_get)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,32, debugstr );
+ }
+ return NULL;
+ }
+
+ sched = l7vs_sched_get(arg->srv_arg.schedmod);
+ if (sched == NULL) {
+ l7vs_protomod_put(pmod);
+ l7vs_lsock_put(lsock);
+ *err = L7VS_CONFIG_ERR_NOSCHED;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_sched_get)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,33, debugstr );
+ }
+ return NULL;
+ }
+
+ // create new destination for sorry-server (weight not set)
+ // FIXME ignore IPv6 address???
+ sorry_dest = (struct l7vs_dest *)l7vs_dest_create((struct sockaddr_in *)&arg->srv_arg.sorry_addr, 0);
+ if (sorry_dest == NULL) {
+ l7vs_sched_put(sched);
+ l7vs_protomod_put(pmod);
+ l7vs_lsock_put(lsock);
+ *err = L7VS_CONFIG_ERR_NOMEM;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_dest_create)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,34, debugstr );
+ }
+ return NULL;
+ }
+
+ srv = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
+ if (srv == NULL) {
+ l7vs_dest_destroy(sorry_dest);
+ l7vs_sched_put(sched);
+ l7vs_protomod_put(pmod);
+ l7vs_lsock_put(lsock);
+ *err = L7VS_CONFIG_ERR_NOMEM;
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,5, "l7vs_service memory allocate error" );
+ return NULL;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", srv, sizeof(struct l7vs_service ) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,35, debugstr );
+ }
+
+ srv->handle = ++service_handle_base;
+ if( TEMP_SERVICEHANDLE == srv->handle ){
+ srv->handle = ++service_handle_base;
+ }
+ ret = pmod->create(&arg->protomod_arg, srv->handle);
+ if (ret != 0) {
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,36, debugstr );
+ }
+ free(srv);
+ l7vs_dest_destroy(sorry_dest);
+ l7vs_sched_put(sched);
+ l7vs_protomod_put(pmod);
+ l7vs_lsock_put(lsock);
+ *err = L7VS_CONFIG_ERR_NOMEM;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure pmod create)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,37, debugstr );
+ }
+ return NULL;
+ }
+
+ for (l = g_list_first(l7vs_service_list); l != NULL;
+ l = g_list_next(l)) {
+ sref = (struct l7vs_service *)l->data;
+
+ if (lsock != sref->lsock) {
+ continue;
+ }
+
+ if (pmod != sref->pm) {
+ continue;
+ }
+
+ if (pmod->compare(srv->handle, sref->handle) != 0) {
+ continue;
+ }
+
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,2, "Virtual service already exists" );
+ l7vs_dest_destroy(sorry_dest);
+ l7vs_sched_put(sched);
+ l7vs_protomod_put(pmod);
+ l7vs_lsock_put(lsock);
+ pmod->destroy(srv->handle);
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,38, debugstr );
+ }
+ free(srv);
+ *err = L7VS_CONFIG_ERR_VS_EXISTS;
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (Duplication service)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,39, debugstr );
+ }
+ return NULL;
+ }
+
+ srv->lsock = lsock;
+ srv->pm = pmod;
+ l7vs_sched_bind(sched, srv);
+
+ // set sorry data
+ srv->sorry_cc = arg->srv_arg.sorry_cc;
+ srv->sorry_dest = sorry_dest;
+ srv->sorry_flag = arg->srv_arg.sorry_flag;
+ // set QoS value
+ srv->qos_threshold_up = arg->srv_arg.qos_threshold_up;
+ srv->qos_threshold_down = arg->srv_arg.qos_threshold_down;
+
+ l7vs_lsock_add_service(lsock, srv);
+ l7vs_service_list = g_list_append(l7vs_service_list, srv);
+
+ // create g_hash_table
+ srv->conn_hash = g_hash_table_new( NULL, NULL );
+
+ // set replicationmode
+ // get the replication area.
+ unsigned int r_size = 0;
+ l7vs_service_repdata * repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory( REP_COMP_SV, &r_size );
+ // if repdata is NULL, Cansel to replication mode
+ if( NULL != repdata ){
+ // if virtuar service number is 1, change mode and copy to the data.
+ if( 1 == g_list_length( l7vs_service_list ) ){
+ l7vs_replication_switch_to_master();
+ // when Syb->Act, Data is saved in a preliminary area of original Service.
+ // The replication data area is calculated.
+ rep_size_num = (r_size * DATA_SIZE) / sizeof(struct l7vs_service_repdata);
+ // get mirror area.
+ rep_mirror = (struct l7vs_service_repdata*)calloc( rep_size_num, sizeof(struct l7vs_service_repdata) );
+ // Copy to the data
+ if( NULL != rep_mirror )memcpy( rep_mirror, repdata, (rep_size_num * sizeof(struct l7vs_service_repdata)) );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %d", rep_mirror, (rep_size_num * sizeof(struct l7vs_service_repdata)) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE, 95, debugstr );
+ }
+ }
+ // if replication data mirror isn't NULL, get a rep_mirror area.
+ if( NULL != rep_mirror )set_replication_data( rep_size_num, rep_mirror, srv );
+ //make replication data
+ make_replication_data( rep_size_num, repdata );
+ }
+
+ //debug output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,40, debugstr );
+ }
+
+ return srv;
+}
+
+
+/*!
+ * append to conn remove list
+ * @param[in] key not use
+ * @param[in] value connection pointer
+ * @param[in] userdata not use
+ */
+static void rmvlistappend( gpointer key, gpointer value, gpointer userdata ){
+ removeconn_list = g_list_append( removeconn_list, value );
+}
+
+
+/*!
+ * service destroy function
+ * @param[in] *srv service pointer
+ * @return void
+ */
+int
+l7vs_service_destroy(struct l7vs_service *srv)
+{
+ struct l7vs_scheduler *sched;
+ struct l7vs_dest * rmv_dest;
+ struct l7vs_conn * rmvconn;
+// struct l7vs_service_repdata * service_replicationdata;
+
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,17, "Service Destroy failure: argument is NULL" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_destroy(struct l7vs_service *srv)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,41, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,42, debugstr );
+ }
+
+ //find service from glist(l7vs_service_list)
+ if( 0 == g_list_length( l7vs_service_list ) ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,3, "Service Destroy failure: service not created" );
+ return -1;
+ }
+ if( NULL == g_list_find( l7vs_service_list, srv ) ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,4, "Service Destroy failure: cannot find in list" );
+ return -1;
+ }
+
+ // remove all hash-table members.
+ g_hash_table_foreach( srv->conn_hash, rmvlistappend, NULL );
+
+ for( removeconn_list = g_list_first( removeconn_list );
+ removeconn_list != NULL; ){
+ rmvconn = (struct l7vs_conn*)removeconn_list->data;
+ l7vs_conn_destroy( rmvconn );
+ removeconn_list = g_list_remove( removeconn_list, rmvconn );
+ }
+
+ // destroy g_hash_table
+ g_hash_table_destroy( srv->conn_hash );
+
+ // remove all dest(exclude sorry_dest)
+ for( srv->dest_list = g_list_first( srv->dest_list ); srv->dest_list != NULL; ){
+ rmv_dest = (struct l7vs_dest*)srv->dest_list->data;
+ srv->dest_list = g_list_remove( srv->dest_list, rmv_dest );
+ l7vs_dest_destroy( rmv_dest );
+ }
+
+ sched = srv->scheduler;
+ l7vs_service_list = g_list_remove(l7vs_service_list, srv);
+ l7vs_sched_unbind(sched, srv);
+ l7vs_dest_destroy(srv->sorry_dest);
+ l7vs_sched_put(sched);
+ l7vs_lsock_remove_service(srv->lsock, srv);
+ l7vs_lsock_put(srv->lsock);
+ srv->pm->destroy(srv->handle);
+ l7vs_protomod_put( srv->pm );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,43, debugstr );
+ }
+ free(srv);
+
+ if( 0 == g_list_length( l7vs_service_list ) ){
+ l7vs_replication_switch_to_slave();
+ }
+
+ //make&set replication data
+// service_replicationdata = (struct l7vs_service_repdata*)calloc(SERVICE_REPLICATION_MAX_NUM, sizeof(struct l7vs_service_repdata) );
+// set_replication_data( SERVICE_REPLICATION_MAX_NUM, &service_replicationdata );
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_destroy(struct l7vs_service *srv) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,44, debugstr );
+ }
+
+ return 0;
+}
+
+/*!
+ * serch from service list.
+ * @param[in] *arg service arg
+ * @return service pointer ( NULL is no lookup )
+ */
+struct l7vs_service *
+l7vs_service_lookup(struct l7vs_service_arg_multi *arg) //checks if the virtual service to be added already exists--Anshu
+{
+ GList *l;
+ struct l7vs_lsock *lsock;
+ struct l7vs_protomod *pmod;
+ struct l7vs_service *s, *sref;
+ int ret = 0;
+
+ if( NULL == arg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,18, "Service lookup failure: agreement is NULL" );
+ return NULL;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_lookup(struct l7vs_service_arg_multi *arg)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,45, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "arg dump" );
+ l7vs_service_arg_multi_c_str( debugstr, arg );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,46, debugstr );
+ }
+
+ lsock = l7vs_lsock_table_lookup(&arg->srv_arg.addr, arg->srv_arg.proto);
+ if (lsock == NULL) {
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL (lsock table not found)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,47, debugstr );
+ }
+ return NULL;
+ }
+
+ pmod = l7vs_protomod_lookup(arg->srv_arg.protomod);
+ if (pmod == NULL) {
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL (protomod not found)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,48, debugstr );
+ }
+ return NULL;
+ }
+
+ s = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
+ if (s == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,6, "l7vs_service memory allocate error" );
+ return NULL;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory allocated : address = %p , size = %zu", s, sizeof(struct l7vs_service) );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,49, debugstr );
+ }
+
+ s->handle = TEMP_SERVICEHANDLE;
+ ret = pmod->create(&arg->protomod_arg, s->handle);
+ if (ret != 0) {
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", s );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,50, debugstr );
+ }
+ free(s);
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,51, debugstr );
+ }
+ return NULL;
+ }
+
+ for (l = g_list_first(l7vs_service_list);
+ l != NULL; l = g_list_next(l)) {
+ sref = (struct l7vs_service *)l->data;
+ if (lsock != sref->lsock) {
+ continue;
+ }
+
+ if (pmod != sref->pm) {
+ continue;
+ }
+
+ if (pmod->compare(s->handle, sref->handle) != 0) {
+ continue;
+ }
+
+ pmod->destroy(s->handle);
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", s );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,52, debugstr );
+ }
+ free(s);
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_lookup(struct l7vs_service_arg_multi *arg)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,53, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "return l7vs_service dump" );
+ l7vs_service_c_str( debugstr, sref );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,54, debugstr );
+ }
+
+ return sref;
+ }
+ if (s != NULL) {
+ pmod->destroy(s->handle);
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "memory free : address = %p", s );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,55, debugstr );
+ }
+ free(s);
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,56, debugstr );
+ }
+ return NULL;
+}
+
+/*!
+ * real server add on service
+ * @param[in] *srv service pointer
+ * @param[in] *darg l7vs_dest_arg pointer
+ * @return success = 0 fail = -1
+ */
+int
+l7vs_service_add_dest(struct l7vs_service *srv,
+ struct l7vs_dest_arg *darg)
+{
+ struct l7vs_dest *d;
+
+ if( NULL == srv || NULL == darg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,19, "Service / add dest : Invalid argument" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ char deststr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,57, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,58, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ memset( deststr, 0, DEBUG_STR_LEN );
+ l7vs_dest_c_str( deststr, (l7vs_dest*)darg );
+ sprintf( debugstr, "dest dump %s", deststr );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,59, debugstr );
+ }
+
+ d = l7vs_service_lookup_dest(srv, &darg->addr);
+ if (d != NULL) {
+ LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, "Cannot add duplicate real service" );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,60, debugstr );
+ }
+ return -1;
+ }
+
+ d = (struct l7vs_dest*) l7vs_dest_create(&darg->addr, darg->weight);
+ if (d == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_REAL_SERVER,1, "Could not allocate memory" );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,61, debugstr );
+ }
+ return -1;
+ }
+ else {
+ LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,6, "ADD_RS: IFRM004: added real server" );
+ }
+
+ srv->dest_list = g_list_append(srv->dest_list, d);
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,62, debugstr );
+ }
+
+ return 0;
+}
+
+/* remove real server pointer function
+ * @param[in] *srv l7vs_service_pointer
+ * @param[in] *darg l7vs_dest pointer
+ * @return success = 0 false = -1
+ */
+int
+l7vs_service_remove_dest(struct l7vs_service *srv,
+ struct l7vs_dest_arg *darg)
+{
+ struct l7vs_dest *d;
+ struct l7vs_conn * tmp_conn;
+
+
+ if( NULL == srv || NULL == darg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,20, "Service / remove dest : Invalid argument");
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ char deststr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,63, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,64, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ memset( deststr, 0, DEBUG_STR_LEN );
+ l7vs_dest_c_str( deststr, (l7vs_dest*)darg );
+ sprintf( debugstr, "dest dump %s", deststr );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,65, debugstr );
+ }
+
+ d = l7vs_service_lookup_dest(srv, &darg->addr);
+ if (d == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_REAL_SERVER,2, "No such real server" );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,66, debugstr );
+ }
+ return -1;
+ }
+ else {
+ LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,7, "DEL_RS: IFRM005: removed real server" );
+ }
+
+ g_hash_table_foreach( srv->conn_hash, rmvlistappend, NULL );
+ for( removeconn_list = g_list_first( removeconn_list ); removeconn_list != NULL; ){
+ tmp_conn = (struct l7vs_conn*)removeconn_list->data;
+ if( d == tmp_conn->dest ){
+ l7vs_conn_destroy( tmp_conn );
+ }
+ removeconn_list = g_list_remove( removeconn_list, tmp_conn );
+ }
+
+ srv->dest_list = g_list_remove(srv->dest_list, d);
+ l7vs_dest_destroy(d);
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,67, debugstr );
+ }
+
+ return 0;
+}
+
+/*!
+ * schedule dest on con.(not use)
+ * @param[in] *srv service pointer
+ * @param[in] *conn l7vs_conn pointer
+ * @return success = 0 false = -1
+ */
+int
+l7vs_service_schedule(struct l7vs_service *srv,
+ struct l7vs_conn *conn)
+{
+ struct l7vs_dest *dest;
+
+ if( NULL == srv || NULL == conn || NULL == srv->scheduler ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,21, "Service / lookup schedule-module : Invalid argument" );
+ return -1;
+ }
+
+ dest = srv->scheduler->schedule(srv, conn);
+ if (dest == NULL) {
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SCHEDULE,1, "no real server defined" );
+ return -1;
+ }
+
+ return l7vs_conn_connect_rs(conn, dest);
+}
+
+
+/*!
+ * NOP
+ */
+int
+l7vs_service_establish(struct l7vs_service *srv,
+ struct l7vs_conn *conn)
+{
+ return 0;
+}
+
+/*!
+ * connection list append conn in service
+ * @param[in] *srv service pointer
+ * @param[in] *conn l7vs_conn pointer
+ * @return void
+ */
+int
+l7vs_service_register_conn(struct l7vs_service *srv,
+ struct l7vs_conn *conn)
+{
+ if( NULL == srv || NULL == conn ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,22, "register connection : Invalid argument" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ char connstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,68, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,69, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ memset( connstr, 0, DEBUG_STR_LEN );
+ l7vs_conn_c_str( connstr, conn );
+ sprintf( debugstr, "conn dump %s", connstr );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,70, debugstr );
+ }
+
+ if( NULL != g_hash_table_lookup( srv->conn_hash, &conn->ciom->fd ) ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, "register connection : conflict connection." );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : -1" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,71, debugstr );
+ }
+ return -1;
+ }
+
+ g_hash_table_insert( srv->conn_hash, &conn->ciom->fd, conn );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,72, debugstr );
+ }
+ return 0;
+}
+
+/*!
+ * connection list delete con in service
+ * @param[in] *srv service pointer
+ * @param[in] *conn l7vs_conn pointer
+ * @return void
+ */
+int
+l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn)
+{
+ if( NULL == srv || NULL == conn ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,23, "remove connection : Invalid argument" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ char connstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn)" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,73, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,74, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ memset( connstr, 0, DEBUG_STR_LEN );
+ l7vs_conn_c_str( connstr, conn );
+ sprintf( debugstr, "conn dump %s", connstr );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,75, debugstr );
+ }
+
+ g_hash_table_remove( srv->conn_hash, &conn->ciom->fd );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,76, debugstr );
+ }
+ return 0;
+}
+
+/*!
+ * destroy all member in all service.
+ *
+ */
+void
+l7vs_service_flush_all(void)
+{
+ GList *l;
+ struct l7vs_service *srv;
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_flush_all()" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,77, debugstr );
+ }
+
+ while ((l = g_list_first(l7vs_service_list)) != NULL) {
+ srv = (struct l7vs_service *)l->data;
+ l7vs_service_destroy( srv );
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_flush_all() return" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,78, debugstr );
+ }
+}
+
+/*!
+ * set QoS(TraficControl) Threshold value
+ * @param[in] *srv service pointer
+ * @param[in] *arg l7vs_service_arg_multi pointer
+ * return 0 = success / -1 = failur
+ */
+int
+l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )
+{
+// struct l7vs_service_repdata * service_replicationdata;
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,24, "Argument srv is NULL" );
+ return -1;
+ }
+ if( NULL == arg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,25, "Argument arg is NULL" );
+ return -1;
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,79, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,80, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "arg dump" );
+ l7vs_service_arg_multi_c_str( debugstr, arg );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,81, debugstr );
+ }
+
+ srv->qos_threshold_up = arg->srv_arg.qos_threshold_up;
+ srv->qos_threshold_down = arg->srv_arg.qos_threshold_down;
+
+ // Get the replication area.
+ unsigned int r_size = 0;
+ l7vs_service_repdata * repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory( REP_COMP_SV, &r_size );
+ // make replication data
+ if( NULL != repdata )make_replication_data( rep_size_num, repdata );
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg ) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,82, debugstr );
+ }
+
+ return 0;
+}
+
+/*!
+ * set Sorry-Server values
+ * @param[in] *srv service pointer
+ * @param[in] *arg l7vs_service_arg_multi pointer
+ * return 0 = success / -1 = failure
+ */
+int
+l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )
+{
+ struct sockaddr_in * saddr;
+// struct l7vs_service_repdata * service_replicationdata;
+
+ if( NULL == srv ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,26, "Argument srv is NULL" );
+ return -1;
+ }
+ if( NULL == arg ){
+ LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,27, "Argument arg is NULL" );
+ return -1;
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,83, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "srv dump" );
+ l7vs_service_c_str( debugstr, srv );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,84, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "arg dump" );
+ l7vs_service_arg_multi_c_str( debugstr, arg );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,85, debugstr );
+ }
+ // set sorry data
+ saddr = (struct sockaddr_in *)&arg->srv_arg.sorry_addr;
+ srv->sorry_dest->addr = *saddr;
+ srv->sorry_cc = arg->srv_arg.sorry_cc;
+ srv->sorry_flag = arg->srv_arg.sorry_flag;
+
+ unsigned int r_size = 0;
+ l7vs_service_repdata *repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory(REP_COMP_SV, &r_size);
+
+ //make replication data
+ if( NULL != repdata)
+ {
+ make_replication_data(rep_size_num, repdata);
+ }
+
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg ) return : 0" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,86, debugstr );
+ }
+
+ return 0;
+}
+
+/*!
+ * get number of l7vs_service list
+ * @param[in] none
+ * @return unsigned int
+ */
+unsigned int
+l7vs_service_get_VSnum()
+{
+ int retval = g_list_length( l7vs_service_list );
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSnum()" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,87, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSnum() return : num = retval" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,88, debugstr );
+ }
+ return retval;
+}
+
+/*!
+ * find and get l7vs_service by number of l7vs_service_list
+ * @param[in] num number of l7vs_service list
+ * return l7vs_service pointer
+ */
+struct l7vs_service *
+l7vs_service_get_VSInfo_byNum( unsigned int num )
+{
+ unsigned int vs_num = g_list_length( l7vs_service_list );
+ if( 0 > num )return NULL;
+ if( 0 == vs_num )return NULL;
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSInfo_byNum( unsigned int num )" );
+ sprintf( debugstr, "%s num = %d", debugstr, num );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,89, debugstr );
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSInfo_byNum( unsigned int num ) return" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,90, debugstr );
+ }
+ return (struct l7vs_service *)g_list_nth_data( l7vs_service_list, num );
+}
+
+/*!
+ * find and get l7vs_service by service-handle
+ * @param[in] in_handle l7vs_service handle
+ * return l7vs_service pointer
+ */
+struct l7vs_service *
+l7vs_service_get_VSInfo_byHandler( handle_t in_handle )
+{
+ GList * l;
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle )" );
+ sprintf( debugstr, "%s, in_handle = %d", debugstr, in_handle );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,91, debugstr );
+ }
+ for ( l = g_list_first(l7vs_service_list); l != NULL; l = g_list_next(l) ){
+ if( ((struct l7vs_service *)l->data)->handle == in_handle ){
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle ) return" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,92, debugstr );
+ }
+ return (struct l7vs_service *)l->data;
+ }
+ }
+ //DEBUG output
+ if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
+ char debugstr[DEBUG_STR_LEN];
+ memset( debugstr, 0, DEBUG_STR_LEN );
+ sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle ) return : NULL" );
+ LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,93, debugstr );
+ }
+ return NULL;
+}
+
+void
+l7vs_service_update_throughput( struct l7vs_service* srv, unsigned long long current_time ) {
+ if ( LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK_BANDWIDTH) ) {
+ char srv_str[DEBUG_STR_LEN];
+ memset( srv_str, 0, DEBUG_STR_LEN );
+ l7vs_service_c_str(srv_str, srv);
+ LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK_BANDWIDTH,1,"in_function: void l7vs_service_update_throughput(struct l7vs_service* srv, unsigned long long current_time) srv=%s, current_time=%llu", srv_str, current_time);
+ }
+ if (srv->pre_recvtime_from_client == current_time - 2) {
+ srv->pre_recvtime_from_client = current_time - 1;
+ srv->pre_recvsize_from_client = srv->cur_recvsize_from_client;
+ srv->cur_recvsize_from_client = 0;
+ }
+ else if (srv->pre_recvtime_from_client != current_time - 1) {
+ srv->pre_recvtime_from_client = current_time - 1;
+ srv->pre_recvsize_from_client = 0;
+ srv->cur_recvsize_from_client = 0;
+ }
+ if (srv->pre_recvtime_from_server == current_time - 2) {
+ srv->pre_recvtime_from_server = current_time - 1;
+ srv->pre_recvsize_from_server = srv->cur_recvsize_from_server;
+ srv->cur_recvsize_from_server = 0;
+ }
+ else if (srv->pre_recvtime_from_server != current_time - 1) {
+ srv->pre_recvtime_from_server = current_time - 1;
+ srv->pre_recvsize_from_server = 0;
+ srv->cur_recvsize_from_server = 0;
+ }
+ if ( LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK_BANDWIDTH) ) {
+ LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_VIRTUAL_SERVICE,2,"out_function: void l7vs_service_update_throughput(struct l7vs_service* srv, unsigned long long current_time)");
+ }
+}