OSDN Git Service

Update INSTALL.ja.utf-8 for new release.
[ultramonkey-l7/ultramonkey-l7-v2.git] / src / service.c
1 /*
2  * @file  service.c
3  * @brief The function  of l7vsd is managed. 
4  * @brief Two or more service takes charge of the 
5  * @brief function respectively. 
6  *
7  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
8  * Copyright (C) 2005  NTT COMWARE Corporation.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  *
25  **********************************************************************/
26 #ifndef __STDC_LIMIT_MACROS
27 #define __STDC_LIMIT_MACROS
28 #endif
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <glib.h>
36 #include <sys/time.h>
37 #include "logger_wrapper.h"
38 #include "l7vs_config.h"
39 #include "l7vs_service.h"
40 #include "l7vs_module.h"
41 #include "l7vs_conn.h"
42 #include "l7vs_dest.h"
43 #include "l7vs_iomuxlist.h"
44 #include "l7vs_lsock.h"
45 #include "l7vs_sched.h"
46
47 #define SERVICE_REPLICATION_MAX_NUM     32
48
49 //! service list pointer
50 static GList * l7vs_service_list;
51
52 //! service handle
53 uint32_t service_handle_base = 0;
54
55 //! remove_conn list pointer
56 static GList * removeconn_list;
57
58 //! replication component id
59 #define REP_COMP_SV     "virtualservice"
60
61 //! replication size
62 static  unsigned int    rep_size_num;
63
64 //! Replication data backup
65 static  l7vs_service_repdata * rep_mirror;
66
67 //static functions
68 static void l7vs_service_put_service_arg(struct l7vs_service_arg_multi *);
69
70 // throughput interval
71 static int throughput_interval = 0;
72
73 /*!
74  * make replication data from l7vs_service structure
75  * @param[in]   num     unsigned int/number of array(l7vs_service_repdata)
76  * @param[out]  **rep_data      l7vs_service_repdata struct double-pointer
77  * @return      int     number currently created / -1 failure
78  */
79 static int
80 make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )
81 {
82         unsigned int loopcnt;
83         unsigned int listcnt;
84         struct  l7vs_service*   sv;
85         struct  l7vs_service_arg_multi* svmulti;
86
87         //argument check
88         if( 1 > num )return -1;
89         if( NULL == rep_data )return -1;
90
91         //DEBUG output
92         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
93                 char    debugstr[DEBUG_STR_LEN];
94                 memset( debugstr, 0, DEBUG_STR_LEN );
95                 sprintf( debugstr, "function make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )");
96                 sprintf( debugstr, "%s num = %d", debugstr, num );
97                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, debugstr );
98         }
99
100         loopcnt = num;
101         listcnt = g_list_length( l7vs_service_list );
102         if( 0 == listcnt )return -1;
103
104         if( loopcnt > listcnt )loopcnt = listcnt;
105         for( unsigned int i = 0; i < loopcnt; ++i ){
106                 sv = (struct l7vs_service*)g_list_nth_data( l7vs_service_list, i );
107                 if( NULL == sv ){
108                         loopcnt = i-1;
109                         break;
110                 }
111                 svmulti = l7vs_service_get_service_arg( sv );
112                 if( NULL == svmulti )return -1;
113                 rep_data[i].addr = svmulti->srv_arg.addr;
114                 rep_data[i].proto       = svmulti->srv_arg.proto;
115                 memcpy( rep_data[i].protomod, svmulti->srv_arg.protomod, L7VS_MODNAME_LEN );
116                 memcpy( rep_data[i].protomod_arg, svmulti->protomod_arg, L7VS_PROTOMOD_MAX_SERVICE_ARG );
117                 //Sorry server information
118                 rep_data[i].sorry_cc    = svmulti->srv_arg.sorry_cc;
119                 rep_data[i].sorry_addr  = svmulti->srv_arg.sorry_addr;
120                 rep_data[i].sorry_flag  = svmulti->srv_arg.sorry_flag;
121                 //QoS information
122                 rep_data[i].qos_threshold_up   = svmulti->srv_arg.qos_threshold_up;
123                 rep_data[i].qos_threshold_down = svmulti->srv_arg.qos_threshold_down;
124
125                 l7vs_service_put_service_arg( svmulti );
126                 //DEBUG output
127                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
128                         char    debugstr[DEBUG_STR_LEN];
129                         memset( debugstr, 0, DEBUG_STR_LEN );
130                         sprintf( debugstr, "rep_data[%d] dump", i);
131                         l7vs_service_repdata_c_str( debugstr, &rep_data[i] );
132                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,6, debugstr );
133                 }
134         }
135
136         //DEBUG output
137         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
138                 char    debugstr[DEBUG_STR_LEN];
139                 memset( debugstr, 0, DEBUG_STR_LEN );
140                 sprintf( debugstr, "function make_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data )");
141                 sprintf( debugstr, "%s return(list num) = %d", debugstr, loopcnt );
142                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,7, debugstr );
143         }
144         return  loopcnt;
145 }
146
147 /*!
148  *
149  */
150 void
151 set_replication_data( unsigned int num, struct l7vs_service_repdata* rep_data, l7vs_service * srv )
152 {
153         struct  l7vs_lsock *    lsock;
154         struct  l7vs_protomod * pmod;
155         struct  l7vs_service *  s;
156         int     ret = 0;
157
158         //argument check
159         if( 0 == num )return;
160         if( NULL == rep_data )return;
161
162         for( unsigned int i = 0; i < num; ++i ){
163                 //lsock lookup
164                 lsock = l7vs_lsock_table_lookup( &rep_data[i].addr, rep_data[i].proto );
165                 if( (NULL == lsock) || (lsock != srv->lsock) )continue;
166                 //protomod lookup
167                 pmod = l7vs_protomod_lookup( rep_data[i].protomod );
168                 if( (NULL == pmod) || (pmod != srv->pm) )continue;
169                 //
170                 s = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
171                 if (s == NULL) {
172                         LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM, 81, "l7vs_service memory allocate error" );
173                         return;
174                 }
175                 //DEBUG output
176                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
177                         char    debugstr[DEBUG_STR_LEN];
178                         memset( debugstr, 0, DEBUG_STR_LEN );
179                         sprintf( debugstr, "memory allocated : address = %p , size = %zu", s, sizeof(struct l7vs_service) );
180                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE, 99, debugstr );
181                 }
182                 s->handle = TEMP_SERVICEHANDLE;
183                 ret = pmod->create( rep_data[i].protomod_arg, s->handle );
184                 if( (0 != ret) || (0 != pmod->compare(s->handle, srv->handle)) ){
185                         pmod->destroy(s->handle);
186                         free(s);
187                         continue;
188                 }
189                 pmod->destroy(s->handle);
190                 free(s);
191                 srv->sorry_cc   = rep_data[i].sorry_cc;
192                 //if sorry is "NULL". Make a sorry_data.
193                 if( NULL == srv->sorry_dest ){
194                         srv->sorry_dest = l7vs_dest_create( (struct sockaddr_in*)&rep_data[i].sorry_addr, 1 );
195                 }else{
196                         memcpy( (void*)&srv->sorry_dest->addr, (void*)&rep_data[i].sorry_addr, sizeof(struct sockaddr_in) );
197                         srv->sorry_dest->weight = 1;
198                         srv->sorry_flag = rep_data[i].sorry_flag;
199                         srv->qos_threshold_up   = rep_data[i].qos_threshold_up;
200                         srv->qos_threshold_down = rep_data[i].qos_threshold_down;
201                 }
202                 break;
203         }
204 }
205
206 /*!
207  * l7vs_servcie_get_service_arg
208  * service arg pointer lookup.
209  * @param[in]   srv     l7vs_service pointer.
210  * @return      l7vs_service_arg_multi pointer
211  */
212 struct l7vs_service_arg_multi *
213 l7vs_service_get_service_arg(struct l7vs_service *srv)
214 {
215         struct l7vs_service_arg_multi *sa;
216         int ret = 0;
217
218         if( NULL == srv ){
219                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,7, "argument srv is NULL");
220                 return NULL;
221         }
222         if( NULL == srv->pm || NULL == srv->lsock || NULL == srv->scheduler ){
223                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,8, "Invalid argument" );
224                 return NULL;
225         }
226
227         //DEBUG output
228         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
229                 char    debugstr[DEBUG_STR_LEN];
230                 memset( debugstr, 0, DEBUG_STR_LEN );
231                 sprintf( debugstr, "function l7vs_service_get_service_arg(struct l7vs_service *srv)");
232                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,8, debugstr );
233                 memset( debugstr, 0, DEBUG_STR_LEN );
234                 sprintf( debugstr, "srv dump" );
235                 l7vs_service_c_str( debugstr, srv );
236                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,9, debugstr );
237         }
238
239         sa = (struct l7vs_service_arg_multi *) calloc(1, sizeof(struct l7vs_service_arg_multi));
240         if (sa == NULL) {
241                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,1, "Could not allocate memory" );
242                 return NULL;
243         }
244         //DEBUG output
245         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
246                 char    debugstr[DEBUG_STR_LEN];
247                 memset( debugstr, 0, DEBUG_STR_LEN );
248                 sprintf( debugstr, "memory allocated : address = %p , size = %zu", sa, sizeof(struct l7vs_service_arg_multi) );
249                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,10, debugstr );
250         }
251
252         ret = srv->pm->service_arg(sa, srv->handle);
253         if (ret == -1) {
254                 //DEBUG output
255                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
256                         char    debugstr[DEBUG_STR_LEN];
257                         memset( debugstr, 0, DEBUG_STR_LEN );
258                         sprintf( debugstr, "memory free : address = %p", sa );
259                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,11, debugstr );
260                 }
261                 free( sa );
262                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROTOCOL,1, "service not found" );
263                 return NULL;
264         }
265
266         sa->srv_arg.len = sizeof(struct l7vs_service_arg_multi);
267         sa->srv_arg.addr = srv->lsock->addr;
268         sa->srv_arg.proto = srv->lsock->proto;
269         sa->srv_arg.persist = 0 /* XXX not yet */;
270         sa->srv_arg.backlog = 5 /* XXX not yet */;
271         strcpy(sa->srv_arg.protomod, srv->pm->modname);
272         strcpy(sa->srv_arg.schedmod, srv->scheduler->modname);
273
274         sa->srv_arg.sorry_cc    = srv->sorry_cc;
275         sa->srv_arg.sorry_flag  = srv->sorry_flag;
276         memcpy( &sa->srv_arg.sorry_addr, &srv->sorry_dest->addr, sizeof(struct sockaddr_in) );
277
278         sa->srv_arg.qos_threshold_up    = srv->qos_threshold_up;
279         sa->srv_arg.qos_threshold_down  = srv->qos_threshold_down;
280
281
282     struct timeval CurrTime;
283     gettimeofday( &CurrTime, NULL );
284     if (throughput_interval == 0) {
285         if ( parameter_is_int_exist( PARAM_COMP_L7VSD, "calc_throughput_interval" ) ) {
286             throughput_interval = parameter_get_int_value( PARAM_COMP_L7VSD, "calc_throughput_interval" );
287         }
288         if (throughput_interval == 0) {
289             throughput_interval = BPS_DEFAULT_INTERVAL;
290         }
291     }
292     unsigned long long cur_recvtime = (CurrTime.tv_sec * 1000000ULL + CurrTime.tv_usec) / throughput_interval;
293     l7vs_service_update_throughput(srv, cur_recvtime);
294     srv->throughput_to_server = srv->pre_recvsize_from_client * 1000000ULL / throughput_interval;
295     srv->throughput_to_client = srv->pre_recvsize_from_server * 1000000ULL / throughput_interval;
296
297
298         if (srv->qos_threshold_up != 0) {
299                 srv->throughput_to_server >= srv->qos_threshold_up
300                                 ? sa->srv_arg.throughput_to_server = srv->qos_threshold_up
301                                 : sa->srv_arg.throughput_to_server = srv->throughput_to_server;
302         } else {
303                 sa->srv_arg.throughput_to_server = srv->throughput_to_server;
304         }
305
306         if (srv->qos_threshold_down != 0) {
307                 srv->throughput_to_client >= srv->qos_threshold_down
308                                 ? sa->srv_arg.throughput_to_client = srv->qos_threshold_down
309                                 : sa->srv_arg.throughput_to_client = srv->throughput_to_client;
310         } else {
311                 sa->srv_arg.throughput_to_client = srv->throughput_to_client;
312         }
313
314         //DEBUG output
315         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
316                 char    debugstr[DEBUG_STR_LEN];
317                 memset( debugstr, 0, DEBUG_STR_LEN );
318                 sprintf( debugstr, "return value : l7vs_service_arg_multi dump" );
319                 l7vs_service_arg_multi_c_str( debugstr, sa );
320                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,12, debugstr );
321         }
322         return sa;
323 }
324
325 /*!
326  * service_arg destroy function.
327  * @param[in] sa        l7vs_service_arg pointer
328  */
329 static void
330 l7vs_service_put_service_arg(struct l7vs_service_arg_multi *sa)
331 {
332         //DEBUG output
333         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
334                 char    debugstr[DEBUG_STR_LEN];
335                 memset( debugstr, 0, DEBUG_STR_LEN );
336                 sprintf( debugstr, "function l7vs_service_put_service_arg(struct l7vs_service_arg_multi *sa)");
337                 sprintf( debugstr, "%s , sa free : address = %p", debugstr, sa );
338                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,13, debugstr );
339         }
340         free(sa);
341 }
342
343
344 /*!
345  * Target real servers of sets of real servers in service are retrieved. 
346  * @param[in]   *srv    service pointer
347  * @param[in]   *sin    IP and port
348  * @return      l7vs_dest* real server struct pointer
349  */
350 struct l7vs_dest *
351 l7vs_service_lookup_dest(struct l7vs_service *srv,
352                          struct sockaddr_in *sin)
353 {
354         GList *l;
355         struct l7vs_dest *d, *found;
356
357         if( NULL == srv ){
358                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,9, "lookup dest : argument \"srv\" is NULL" );
359                 return NULL;
360         }
361         if( NULL == sin ){
362                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,10, "lookup dest : argument \"sin\" is NULL" );
363                 return NULL;
364         }
365
366         //DEBUG output
367         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
368                 char    debugstr[DEBUG_STR_LEN];
369                 memset( debugstr, 0, DEBUG_STR_LEN );
370                 sprintf( debugstr, "function l7vs_service_lookup_dest(struct l7vs_service *srv, struct sockaddr_in *sin)" );
371                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,14, debugstr );
372                 memset( debugstr, 0, DEBUG_STR_LEN );
373                 sprintf( debugstr, "srv dump" );
374                 l7vs_service_c_str( debugstr, srv );
375                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,15, debugstr );
376                 memset( debugstr, 0, DEBUG_STR_LEN );
377                 sprintf( debugstr, "sin dump " );
378                 switch( sin->sin_family ){
379                 case AF_UNIX:
380                         sprintf( debugstr, "%s socket family = AF_UNIX(PF_UNIX)", debugstr );
381                         break;
382                 case AF_INET:
383                         sprintf( debugstr, "%s socket family = AF_INET(PF_INET)", debugstr );
384                         break;
385                 default:
386                         sprintf( debugstr, "%s socket family = %d", debugstr, sin->sin_family );
387                 }
388                 sprintf( debugstr, "%s port no = %d", debugstr, ntohs( sin->sin_port ) );
389                 sprintf( debugstr, "%s address = %s", debugstr, inet_ntoa( sin->sin_addr ) );
390                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,16, debugstr );
391         }
392
393         found = NULL;
394         for (l = g_list_first(srv->dest_list); l != NULL; l = g_list_next(l)) {
395                 d = (struct l7vs_dest *)l->data;
396                 if ((d->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && (d->addr.sin_port == sin->sin_port)) {
397                         found = d;
398                         break;
399                 }
400         }
401
402         //DEBUG output
403         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
404                 char    debugstr[DEBUG_STR_LEN];
405                 memset( debugstr, 0, DEBUG_STR_LEN );
406                 sprintf( debugstr, "return value = %p", found );
407                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,17, debugstr );
408         }
409
410         return found;
411 }
412
413 /*!
414  *
415  * @param[out] **sas    l7vs_service_arg pointer list
416  * @param[out] *num     pointer list count
417  * @return              pointer list count
418
419  */
420 int
421 l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)
422 {
423         GList *l;
424         struct l7vs_service *srv;
425         struct l7vs_service_arg_multi *r, *s;
426         struct l7vs_service_arg_multi **sa;
427         int i, n, len;
428
429         if( NULL == sas ){
430                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,11, "list service_arg : argument \"sas\" is NULL" );
431                 return -1;
432         }
433         if( NULL == num ){
434                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,12, "list service_arg : argument \"num\" is NULL" );
435                 return -1;
436         }
437
438         //DEBUG output
439         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
440                 char    debugstr[DEBUG_STR_LEN];
441                 memset( debugstr, 0, DEBUG_STR_LEN );
442                 sprintf( debugstr, "function l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)" );
443                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,18, debugstr );
444         }
445
446         n = g_list_length(l7vs_service_list);
447         if (n == 0) {
448                 *sas = NULL;
449                 *num = 0;
450                 return 0;
451         }
452
453         sa = (struct l7vs_service_arg_multi **)calloc(n, sizeof(*sa));
454         if (sa == NULL) {
455                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,2, "list service_arg : Could not allocate memory" );
456                 return -1;
457         }
458         //DEBUG output
459         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
460                 char    debugstr[DEBUG_STR_LEN];
461                 memset( debugstr, 0, DEBUG_STR_LEN );
462                 sprintf( debugstr, "memory allocated : address = %p , size = %zu", sa, sizeof(struct l7vs_service_arg_multi) );
463                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,19, debugstr );
464         }
465
466         len = 0;
467         l = g_list_first(l7vs_service_list);
468         for (i = 0; i < n; i++) {
469                 srv = (struct l7vs_service *)l->data;
470                 sa[i] = l7vs_service_get_service_arg(srv);
471                 if (sa[i] == NULL) {
472                         for (i-- ; i >= 0; i--) {
473                                 l7vs_service_put_service_arg(sa[i]);
474                         }
475                         //DEBUG output
476                         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
477                                 char    debugstr[DEBUG_STR_LEN];
478                                 memset( debugstr, 0, DEBUG_STR_LEN );
479                                 sprintf( debugstr, "memory free : address = %p", sa );
480                                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,20, debugstr );
481                         }
482                         free(sa);
483                         return -1;
484                 }
485                 len += sa[i]->srv_arg.len;
486                 l = g_list_next(l);
487         }
488
489         r = (struct l7vs_service_arg_multi *)malloc(len);
490         if (r == NULL) {
491                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,3, "list service_arg : Could not allocate memory" );
492                 return -1;
493         }
494         //DEBUG output
495         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
496                 char    debugstr[DEBUG_STR_LEN];
497                 memset( debugstr, 0, DEBUG_STR_LEN );
498                 sprintf( debugstr, "memory allocated : address = %p , size = %d", r, len );
499                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,21, debugstr );
500         }
501
502         s = r;
503         for (i = 0; i < n; i++) {
504                 memcpy(s, sa[i], sa[i]->srv_arg.len);
505                 s = (struct l7vs_service_arg_multi *)((uint8_t *)s + sa[i]->srv_arg.len);
506                 l7vs_service_put_service_arg(sa[i]);
507         }
508         //DEBUG output
509         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
510                 char    debugstr[DEBUG_STR_LEN];
511                 memset( debugstr, 0, DEBUG_STR_LEN );
512                 sprintf( debugstr, "memory free : address = %p", sa );
513                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,22, debugstr );
514         }
515         free(sa);
516         *sas = r;
517         *num = n;
518
519         //DEBUG output
520         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
521                 char    debugstr[DEBUG_STR_LEN];
522                 memset( debugstr, 0, DEBUG_STR_LEN );
523                 sprintf( debugstr, "function l7vs_service_list_service_arg(struct l7vs_service_arg_multi **sas, int *num)" );
524                 sprintf( debugstr, "%s return : len = %d , sas = %p , num = %d", debugstr, len, sas, *num );
525                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,23, debugstr );
526         }
527
528         return len;
529 }
530
531 /*!
532  * get l7vs_dest_arg lists
533  * @param[in] *srv      service pointer
534  * @param[out] **das    l7vs_dest_arg pointer list
535  * @return              pointer list count
536  */
537 int
538 l7vs_service_list_dest_arg(struct l7vs_service *srv,
539                            struct l7vs_dest_arg **das)
540 {
541         GList *l;
542         struct l7vs_dest *d;
543         struct l7vs_dest_arg *darg;
544         int i, num;
545
546         if( NULL == srv ){
547                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,13, "list dest_arg : argument \"srv\" is NULL" );
548                 return -1;
549         }
550         if( NULL == das ){
551                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,14, "list dest_arg : argument \"das\" is NULL" );
552                 return -1;
553         }
554
555         //DEBUG output
556         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
557                 char    debugstr[DEBUG_STR_LEN];
558                 memset( debugstr, 0, DEBUG_STR_LEN );
559                 sprintf( debugstr, "function l7vs_service_list_dest_arg(struct l7vs_service *srv, struct l7vs_dest_arg **das)" );
560                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,24, debugstr );
561                 memset( debugstr, 0, DEBUG_STR_LEN );
562                 sprintf( debugstr, "srv dump" );
563                 l7vs_service_c_str( debugstr, srv );
564                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,25, debugstr );
565         }
566
567         num = g_list_length(srv->dest_list);
568         if (num == 0) {
569                 *das = NULL;
570                 return num;
571         }
572
573         darg = (struct l7vs_dest_arg *)malloc(num * sizeof(*darg));
574         if (darg == NULL) {
575                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,4, "Could not allocate memory" );
576                 return -1;
577         }
578         //DEBUG output
579         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
580                 char    debugstr[DEBUG_STR_LEN];
581                 memset( debugstr, 0, DEBUG_STR_LEN );
582                 sprintf( debugstr, "memory allocated : address = %p , size = %zu", darg, ( num * sizeof(*darg) ) );
583                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,26, debugstr );
584         }
585
586         i = 0;
587         for (l = g_list_first(srv->dest_list); l != NULL; l = g_list_next(l)) {
588                 d = (struct l7vs_dest *)l->data;
589                 l7vs_dest_to_arg(d, &darg[i]);
590                 i++;
591         }
592
593         *das = darg;
594         //DEBUG output
595         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
596                 char    debugstr[DEBUG_STR_LEN];
597                 memset( debugstr, 0, DEBUG_STR_LEN );
598                 sprintf( debugstr, "function l7vs_service_list_dest_arg(struct l7vs_service *srv, struct l7vs_dest_arg **das)" );
599                 sprintf( debugstr, "%s return : num = %d , **darg = %p", debugstr, num, das );
600                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,27, debugstr );
601         }
602
603         return num;
604 }
605
606 /*!
607  * create service instance. and set service value.
608  * @param[in]   *arg    l7vs_service_arg pointer
609  * @param[out]  *err    error code
610  * @return              l7vs_service pointer
611  */
612 struct l7vs_service *
613 l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)
614 {
615         struct l7vs_protomod *pmod;
616         struct l7vs_scheduler *sched;
617         struct l7vs_service *srv, *sref;
618         struct l7vs_lsock *lsock;
619         struct l7vs_dest *sorry_dest;   //! sorry-server destination
620 //      struct l7vs_service_repdata *   service_replicationdata;
621
622         int ret = 0;
623         GList *l;
624
625         if( NULL == arg ){
626                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,15, "Could not create service : argument \"arg\" is NULL" );
627                 return NULL;
628         }
629         if( NULL == err ){
630                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,16, "Could not create service : argument \"err\" is NULL" );
631                 return NULL;
632         }
633
634         //DEBUG output
635         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
636                 char    debugstr[DEBUG_STR_LEN];
637                 memset( debugstr, 0, DEBUG_STR_LEN );
638                 sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)" );
639                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,28, debugstr );
640                 memset( debugstr, 0, DEBUG_STR_LEN );
641                 l7vs_service_arg_multi_c_str( debugstr, arg );
642                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,29, debugstr );
643         }
644
645         *err = 0;
646
647         /* max service guard */
648         if( g_list_length( l7vs_service_list ) >= MAX_SERVICES ){
649                 LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,4, "l7vsd max service is %d, new virtual service can't create.", MAX_SERVICES );
650                 *err = L7VS_CONFIG_ERR_MAXVS_EXISTS;
651                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE )) {
652                         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" );
653                 }
654                 return NULL;
655         }
656
657         lsock = l7vs_lsock_get(&arg->srv_arg.addr, arg->srv_arg.proto, arg->srv_arg.backlog);
658         if (lsock == NULL) {
659                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,1, "Could not create listen socket" );
660                 *err = L7VS_CONFIG_ERR_NOSOCK;
661                 //debug output
662                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
663                         char    debugstr[DEBUG_STR_LEN];
664                         memset( debugstr, 0, DEBUG_STR_LEN );
665                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_lsock_get)" );
666                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,31, debugstr );
667                 }
668                 return NULL;
669         }
670
671         pmod = l7vs_protomod_get(arg->srv_arg.protomod);
672         if (pmod == NULL) {
673                 l7vs_lsock_put(lsock);
674                 *err = L7VS_CONFIG_ERR_NOMEM;
675                 //debug output
676                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
677                         char    debugstr[DEBUG_STR_LEN];
678                         memset( debugstr, 0, DEBUG_STR_LEN );
679                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_protomod_get)" );
680                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,32, debugstr );
681                 }
682                 return NULL;
683         }
684
685         sched = l7vs_sched_get(arg->srv_arg.schedmod);
686         if (sched == NULL) {
687                 l7vs_protomod_put(pmod);
688                 l7vs_lsock_put(lsock);
689                 *err = L7VS_CONFIG_ERR_NOSCHED;
690                 //debug output
691                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
692                         char    debugstr[DEBUG_STR_LEN];
693                         memset( debugstr, 0, DEBUG_STR_LEN );
694                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_sched_get)" );
695                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,33, debugstr );
696                 }
697                 return NULL;
698         }
699
700         // create new destination for sorry-server (weight not set)
701     // FIXME ignore IPv6 address???
702         sorry_dest = (struct l7vs_dest *)l7vs_dest_create((struct sockaddr_in *)&arg->srv_arg.sorry_addr, 0);
703         if (sorry_dest == NULL) {
704                 l7vs_sched_put(sched);
705                 l7vs_protomod_put(pmod);
706                 l7vs_lsock_put(lsock);
707                  *err = L7VS_CONFIG_ERR_NOMEM;
708                 //debug output
709                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
710                         char    debugstr[DEBUG_STR_LEN];
711                         memset( debugstr, 0, DEBUG_STR_LEN );
712                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure l7vs_dest_create)" );
713                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,34, debugstr );
714                 }
715                 return NULL;
716         }
717
718         srv = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
719         if (srv == NULL) {
720                 l7vs_dest_destroy(sorry_dest);
721                 l7vs_sched_put(sched);
722                 l7vs_protomod_put(pmod);
723                 l7vs_lsock_put(lsock);
724                 *err = L7VS_CONFIG_ERR_NOMEM;
725                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,5, "l7vs_service memory allocate error" );
726                 return NULL;
727         }
728         //DEBUG output
729         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
730                 char    debugstr[DEBUG_STR_LEN];
731                 memset( debugstr, 0, DEBUG_STR_LEN );
732                 sprintf( debugstr, "memory allocated : address = %p , size = %zu", srv, sizeof(struct l7vs_service ) );
733                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,35, debugstr );
734         }
735
736         srv->handle = ++service_handle_base;
737         if( TEMP_SERVICEHANDLE == srv->handle ){
738                 srv->handle = ++service_handle_base;
739         }
740         ret = pmod->create(&arg->protomod_arg, srv->handle);
741         if (ret != 0) {
742                 //DEBUG output
743                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
744                         char    debugstr[DEBUG_STR_LEN];
745                         memset( debugstr, 0, DEBUG_STR_LEN );
746                         sprintf( debugstr, "memory free : address = %p", srv );
747                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,36, debugstr );
748                 }
749                 free(srv);
750                 l7vs_dest_destroy(sorry_dest);
751                 l7vs_sched_put(sched);
752                 l7vs_protomod_put(pmod);
753                 l7vs_lsock_put(lsock);
754                 *err = L7VS_CONFIG_ERR_NOMEM;
755                 //debug output
756                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
757                         char    debugstr[DEBUG_STR_LEN];
758                         memset( debugstr, 0, DEBUG_STR_LEN );
759                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (failure pmod create)" );
760                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,37, debugstr );
761                 }
762                 return NULL;
763         }
764
765         for (l = g_list_first(l7vs_service_list); l != NULL;
766              l = g_list_next(l)) {
767                 sref = (struct l7vs_service *)l->data;
768
769                 if (lsock != sref->lsock) {
770                         continue;
771                 }
772
773                 if (pmod != sref->pm) {
774                         continue;
775                 }
776
777                 if (pmod->compare(srv->handle, sref->handle) != 0) {
778                         continue;
779                 }
780
781                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,2, "Virtual service already exists" );
782                 l7vs_dest_destroy(sorry_dest);
783                 l7vs_sched_put(sched);
784                 l7vs_protomod_put(pmod);
785                 l7vs_lsock_put(lsock);
786                 pmod->destroy(srv->handle);
787                 //DEBUG output
788                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
789                         char    debugstr[DEBUG_STR_LEN];
790                         memset( debugstr, 0, DEBUG_STR_LEN );
791                         sprintf( debugstr, "memory free : address = %p", srv );
792                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,38, debugstr );
793                 }
794                 free(srv);
795                 *err = L7VS_CONFIG_ERR_VS_EXISTS;
796                 //debug output
797                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
798                         char    debugstr[DEBUG_STR_LEN];
799                         memset( debugstr, 0, DEBUG_STR_LEN );
800                         sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) return : NULL (Duplication service)" );
801                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,39, debugstr );
802                 }
803                 return NULL;
804         }
805
806         srv->lsock = lsock;
807         srv->pm = pmod;
808         l7vs_sched_bind(sched, srv);
809
810         // set sorry data
811         srv->sorry_cc   = arg->srv_arg.sorry_cc;
812         srv->sorry_dest = sorry_dest;
813         srv->sorry_flag = arg->srv_arg.sorry_flag;
814         // set QoS value
815         srv->qos_threshold_up   = arg->srv_arg.qos_threshold_up;
816         srv->qos_threshold_down = arg->srv_arg.qos_threshold_down;
817
818         l7vs_lsock_add_service(lsock, srv);
819         l7vs_service_list = g_list_append(l7vs_service_list, srv);
820
821         // create g_hash_table
822         srv->conn_hash = g_hash_table_new( NULL, NULL );
823
824         // set replicationmode
825         // get the replication area.
826         unsigned int r_size = 0;
827         l7vs_service_repdata * repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory( REP_COMP_SV, &r_size );
828         // if repdata is NULL, Cansel to replication mode
829         if( NULL != repdata ){
830                 // if virtuar service number is 1, change mode and copy to the data.
831                 if( 1 == g_list_length( l7vs_service_list ) ){
832                         l7vs_replication_switch_to_master();
833                         // when Syb->Act, Data is saved in a preliminary area of original Service.
834                         // The replication data area is calculated.  
835                         rep_size_num = (r_size * DATA_SIZE) / sizeof(struct l7vs_service_repdata);
836                         // get mirror area.
837                         rep_mirror = (struct l7vs_service_repdata*)calloc( rep_size_num, sizeof(struct l7vs_service_repdata) );
838                         // Copy to the data
839                         if( NULL != rep_mirror )memcpy( rep_mirror, repdata, (rep_size_num * sizeof(struct l7vs_service_repdata)) );
840                         //DEBUG output
841                         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
842                                 char    debugstr[DEBUG_STR_LEN];
843                                 memset( debugstr, 0, DEBUG_STR_LEN );
844                                 sprintf( debugstr, "memory allocated : address = %p , size = %d", rep_mirror, (rep_size_num * sizeof(struct l7vs_service_repdata)) );
845                                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE, 100, debugstr );
846                         }
847                 }
848                 // if replication data mirror isn't NULL, get a rep_mirror area.
849                 if( NULL != rep_mirror )set_replication_data( rep_size_num, rep_mirror, srv );
850                 //make replication data
851                 make_replication_data( rep_size_num, repdata );
852         }
853
854         //debug output
855         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
856                 char    debugstr[DEBUG_STR_LEN];
857                 memset( debugstr, 0, DEBUG_STR_LEN );
858                 sprintf( debugstr, "function l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err)" );
859                 l7vs_service_c_str( debugstr, srv );
860                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,40, debugstr );
861         }
862
863         return srv;
864 }
865
866
867 /*!
868  * append to conn remove list
869  * @param[in]   key     not use
870  * @param[in]   value   connection pointer
871  * @param[in]   userdata not use
872  */
873 static void             rmvlistappend( gpointer key, gpointer value, gpointer userdata ){
874         removeconn_list = g_list_append( removeconn_list, value );
875 }
876
877
878 /*!
879  * service destroy function
880  * @param[in] *srv      service pointer
881  * @return    void
882  */
883 int
884 l7vs_service_destroy(struct l7vs_service *srv)
885 {
886         struct l7vs_scheduler *sched;
887         struct l7vs_dest * rmv_dest;
888         struct l7vs_conn * rmvconn;
889 //      struct l7vs_service_repdata *   service_replicationdata;
890
891
892         if( NULL == srv ){
893                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,17, "Service Destroy failure: argument is NULL" );
894                 return -1;
895         }
896         
897         //DEBUG output
898         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
899                 char    debugstr[DEBUG_STR_LEN];
900                 memset( debugstr, 0, DEBUG_STR_LEN );
901                 sprintf( debugstr, "function l7vs_service_destroy(struct l7vs_service *srv)" );
902                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,41, debugstr );
903                 memset( debugstr, 0, DEBUG_STR_LEN );
904                 sprintf( debugstr, "srv dump" );
905                 l7vs_service_c_str( debugstr, srv );
906                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,42, debugstr );
907         }
908
909         //find service from glist(l7vs_service_list)
910         if( 0 == g_list_length( l7vs_service_list ) ){
911                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,3, "Service Destroy failure: service not created" );
912                 return -1;
913         }
914         if( NULL == g_list_find( l7vs_service_list, srv ) ){
915                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,4, "Service Destroy failure: cannot find in list" );
916                 return -1;
917         }
918         
919         // remove all hash-table members.
920         g_hash_table_foreach( srv->conn_hash, rmvlistappend, NULL );
921         
922         for( removeconn_list = g_list_first( removeconn_list );
923              removeconn_list != NULL; ){
924                 rmvconn = (struct l7vs_conn*)removeconn_list->data;
925                 l7vs_conn_destroy( rmvconn );
926                 removeconn_list = g_list_remove( removeconn_list, rmvconn );
927         }
928         
929         // destroy g_hash_table
930         g_hash_table_destroy( srv->conn_hash );
931
932         // remove all dest(exclude sorry_dest)
933         for( srv->dest_list = g_list_first( srv->dest_list ); srv->dest_list != NULL; ){
934                 rmv_dest = (struct l7vs_dest*)srv->dest_list->data;
935                 srv->dest_list = g_list_remove( srv->dest_list, rmv_dest );
936                 l7vs_dest_destroy( rmv_dest );
937         }
938
939         sched = srv->scheduler;
940         l7vs_service_list = g_list_remove(l7vs_service_list, srv);
941         l7vs_sched_unbind(sched, srv);
942         l7vs_dest_destroy(srv->sorry_dest);
943         l7vs_sched_put(sched);
944         l7vs_lsock_remove_service(srv->lsock, srv);
945         l7vs_lsock_put(srv->lsock);
946         srv->pm->destroy(srv->handle);
947         l7vs_protomod_put( srv->pm );
948         //DEBUG output
949         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
950                 char    debugstr[DEBUG_STR_LEN];
951                 memset( debugstr, 0, DEBUG_STR_LEN );
952                 sprintf( debugstr, "memory free : address = %p", srv );
953                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,43, debugstr );
954         }
955         free(srv);
956
957         if( 0 == g_list_length( l7vs_service_list ) ){
958                 l7vs_replication_switch_to_slave();
959         }
960
961         //make&set replication data
962 //      service_replicationdata = (struct l7vs_service_repdata*)calloc(SERVICE_REPLICATION_MAX_NUM, sizeof(struct l7vs_service_repdata) );
963 //      set_replication_data( SERVICE_REPLICATION_MAX_NUM, &service_replicationdata );
964
965         //DEBUG output
966         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
967                 char    debugstr[DEBUG_STR_LEN];
968                 memset( debugstr, 0, DEBUG_STR_LEN );
969                 sprintf( debugstr, "function l7vs_service_destroy(struct l7vs_service *srv) return : 0" );
970                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,44, debugstr );
971         }
972
973         return 0;
974 }
975
976 /*!
977  * serch from service list.
978  * @param[in]   *arg service arg
979  * @return      service pointer ( NULL is no lookup )
980  */
981 struct l7vs_service *
982 l7vs_service_lookup(struct l7vs_service_arg_multi *arg) //checks if the virtual service to be added already exists--Anshu
983 {
984         GList *l;
985         struct l7vs_lsock *lsock;
986         struct l7vs_protomod *pmod;
987         struct l7vs_service *s, *sref;
988         int ret = 0;
989
990         if( NULL == arg ){
991                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,18, "Service lookup failure: agreement is NULL" );
992                 return NULL;
993         }
994
995         //DEBUG output
996         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
997                 char    debugstr[DEBUG_STR_LEN];
998                 memset( debugstr, 0, DEBUG_STR_LEN );
999                 sprintf( debugstr, "function l7vs_service_lookup(struct l7vs_service_arg_multi *arg)" );
1000                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,45, debugstr );
1001                 memset( debugstr, 0, DEBUG_STR_LEN );
1002                 sprintf( debugstr, "arg dump" );
1003                 l7vs_service_arg_multi_c_str( debugstr, arg );
1004                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,46, debugstr );
1005         }
1006
1007         lsock = l7vs_lsock_table_lookup(&arg->srv_arg.addr, arg->srv_arg.proto);
1008         if (lsock == NULL) {
1009                 //DEBUG output
1010                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1011                         char    debugstr[DEBUG_STR_LEN];
1012                         memset( debugstr, 0, DEBUG_STR_LEN );
1013                         sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL (lsock table not found)" );
1014                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,47, debugstr );
1015                 }
1016                 return NULL;
1017         }
1018
1019         pmod = l7vs_protomod_lookup(arg->srv_arg.protomod);
1020         if (pmod == NULL) {
1021                 //DEBUG output
1022                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1023                         char    debugstr[DEBUG_STR_LEN];
1024                         memset( debugstr, 0, DEBUG_STR_LEN );
1025                         sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL (protomod not found)" );
1026                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,48, debugstr );
1027                 }
1028                 return NULL;
1029         }
1030
1031         s = (struct l7vs_service *) calloc(1, sizeof(struct l7vs_service));
1032         if (s == NULL) {
1033                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,6, "l7vs_service memory allocate error" );
1034                 return NULL;
1035         }
1036         //DEBUG output
1037         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1038                 char    debugstr[DEBUG_STR_LEN];
1039                 memset( debugstr, 0, DEBUG_STR_LEN );
1040                 sprintf( debugstr, "memory allocated : address = %p , size = %zu", s, sizeof(struct l7vs_service) );
1041                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,49, debugstr );
1042         }
1043
1044         s->handle = TEMP_SERVICEHANDLE;
1045         ret = pmod->create(&arg->protomod_arg, s->handle);
1046         if (ret != 0) {
1047                 //DEBUG output
1048                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1049                         char    debugstr[DEBUG_STR_LEN];
1050                         memset( debugstr, 0, DEBUG_STR_LEN );
1051                         sprintf( debugstr, "memory free : address = %p", s );
1052                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,50, debugstr );
1053                 }
1054                 free(s);
1055                 //DEBUG output
1056                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1057                         char    debugstr[DEBUG_STR_LEN];
1058                         memset( debugstr, 0, DEBUG_STR_LEN );
1059                         sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL" );
1060                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,51, debugstr );
1061                 }
1062                 return NULL;
1063         }
1064
1065         for (l = g_list_first(l7vs_service_list);
1066              l != NULL; l = g_list_next(l)) {
1067                 sref = (struct l7vs_service *)l->data;
1068                 if (lsock != sref->lsock) {
1069                         continue;
1070                 }
1071
1072                 if (pmod != sref->pm) {
1073                         continue;
1074                 }
1075
1076                 if (pmod->compare(s->handle, sref->handle) != 0) {
1077                         continue;
1078                 }
1079
1080                 pmod->destroy(s->handle);
1081                 //DEBUG output
1082                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1083                         char    debugstr[DEBUG_STR_LEN];
1084                         memset( debugstr, 0, DEBUG_STR_LEN );
1085                         sprintf( debugstr, "memory free : address = %p", s );
1086                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,52, debugstr );
1087                 }
1088                 free(s);
1089                 //DEBUG output
1090                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1091                         char    debugstr[DEBUG_STR_LEN];
1092                         memset( debugstr, 0, DEBUG_STR_LEN );
1093                         sprintf( debugstr, "function l7vs_service_lookup(struct l7vs_service_arg_multi *arg)" );
1094                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,53, debugstr );
1095                         memset( debugstr, 0, DEBUG_STR_LEN );
1096                         sprintf( debugstr, "return l7vs_service dump" );
1097                         l7vs_service_c_str( debugstr, sref );
1098                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,54, debugstr );
1099                 }
1100
1101                 return sref;
1102         }
1103         if (s != NULL) {
1104                 pmod->destroy(s->handle);
1105                 //DEBUG output
1106                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1107                         char    debugstr[DEBUG_STR_LEN];
1108                         memset( debugstr, 0, DEBUG_STR_LEN );
1109                         sprintf( debugstr, "memory free : address = %p", s );
1110                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,55, debugstr );
1111                 }
1112                 free(s);
1113         } 
1114         //DEBUG output
1115         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1116                 char    debugstr[DEBUG_STR_LEN];
1117                 memset( debugstr, 0, DEBUG_STR_LEN );
1118                 sprintf( debugstr, "l7vs_service_lookup(struct l7vs_service_arg_multi *arg) return : NULL" );
1119                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,56, debugstr );
1120         }
1121         return NULL;
1122 }
1123
1124 /*!
1125  * real server add on service
1126  * @param[in]   *srv    service pointer
1127  * @param[in]   *darg   l7vs_dest_arg pointer
1128  * @return              success = 0 fail = -1
1129  */
1130 int
1131 l7vs_service_add_dest(struct l7vs_service *srv,
1132                       struct l7vs_dest_arg *darg)
1133 {
1134         struct l7vs_dest *d;
1135
1136         if( NULL == srv || NULL == darg ){
1137                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,19, "Service / add dest : Invalid argument" );
1138                 return -1;
1139         }
1140
1141         //DEBUG output
1142         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1143                 char    debugstr[DEBUG_STR_LEN];
1144                 char    deststr[DEBUG_STR_LEN];
1145                 memset( debugstr, 0, DEBUG_STR_LEN );
1146                 sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg)" );
1147                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,57, debugstr );
1148                 memset( debugstr, 0, DEBUG_STR_LEN );
1149                 sprintf( debugstr, "srv dump" );
1150                 l7vs_service_c_str( debugstr, srv );
1151                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,58, debugstr );
1152                 memset( debugstr, 0, DEBUG_STR_LEN );
1153                 memset( deststr, 0, DEBUG_STR_LEN );
1154                 l7vs_dest_c_str( deststr, (l7vs_dest*)darg );
1155                 sprintf( debugstr, "dest dump %s", deststr );
1156                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,59, debugstr );
1157         }
1158
1159         d = l7vs_service_lookup_dest(srv, &darg->addr);
1160         if (d != NULL) {
1161                 LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, "Cannot add duplicate real service" );
1162                 //DEBUG output
1163                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1164                         char    debugstr[DEBUG_STR_LEN];
1165                         memset( debugstr, 0, DEBUG_STR_LEN );
1166                         sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
1167                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,60, debugstr );
1168                 }
1169                 return -1;
1170         }
1171
1172         d = (struct l7vs_dest*) l7vs_dest_create(&darg->addr, darg->weight);
1173         if (d == NULL) {
1174                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_REAL_SERVER,1, "Could not allocate memory" );
1175                 //DEBUG output
1176                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1177                         char    debugstr[DEBUG_STR_LEN];
1178                         memset( debugstr, 0, DEBUG_STR_LEN );
1179                         sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
1180                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,61, debugstr );
1181                 }
1182                 return -1;
1183         }
1184                 else {
1185                         LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,6, "ADD_RS: IFRM004: added real server" );
1186                 }
1187         
1188         srv->dest_list = g_list_append(srv->dest_list, d);
1189
1190         //DEBUG output
1191         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1192                 char    debugstr[DEBUG_STR_LEN];
1193                 memset( debugstr, 0, DEBUG_STR_LEN );
1194                 sprintf( debugstr, "function l7vs_service_add_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : 0" );
1195                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,62, debugstr );
1196         }
1197
1198         return 0;
1199 }
1200
1201 /* remove real server pointer function
1202  * @param[in]   *srv    l7vs_service_pointer
1203  * @param[in]   *darg   l7vs_dest pointer
1204  * @return              success = 0 false = -1
1205  */
1206 int
1207 l7vs_service_remove_dest(struct l7vs_service *srv,
1208                          struct l7vs_dest_arg *darg)
1209 {
1210         struct l7vs_dest *d;
1211         struct l7vs_conn * tmp_conn;
1212
1213
1214         if( NULL == srv || NULL == darg ){
1215                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,20, "Service / remove dest : Invalid argument");
1216                 return -1;
1217         }
1218
1219         //DEBUG output
1220         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1221                 char    debugstr[DEBUG_STR_LEN];
1222                 char    deststr[DEBUG_STR_LEN];
1223                 memset( debugstr, 0, DEBUG_STR_LEN );
1224                 sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg)" );
1225                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,63, debugstr );
1226                 memset( debugstr, 0, DEBUG_STR_LEN );
1227                 sprintf( debugstr, "srv dump" );
1228                 l7vs_service_c_str( debugstr, srv );
1229                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,64, debugstr );
1230                 memset( debugstr, 0, DEBUG_STR_LEN );
1231                 memset( deststr, 0, DEBUG_STR_LEN );
1232                 l7vs_dest_c_str( deststr, (l7vs_dest*)darg );
1233                 sprintf( debugstr, "dest dump %s", deststr );
1234                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,65, debugstr );
1235         }
1236
1237         d = l7vs_service_lookup_dest(srv, &darg->addr);
1238         if (d == NULL) {
1239                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_REAL_SERVER,2, "No such real server" );
1240                 //DEBUG output
1241                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1242                         char    debugstr[DEBUG_STR_LEN];
1243                         memset( debugstr, 0, DEBUG_STR_LEN );
1244                         sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : -1" );
1245                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,66, debugstr );
1246                 }
1247                 return -1;
1248         }
1249         else {
1250                 LOGGER_PUT_LOG_INFO( LOG_CAT_L7VSD_VIRTUAL_SERVICE,7, "DEL_RS: IFRM005: removed real server" );
1251         }
1252
1253         g_hash_table_foreach( srv->conn_hash, rmvlistappend, NULL );
1254         for( removeconn_list = g_list_first( removeconn_list ); removeconn_list != NULL; ){
1255                 tmp_conn = (struct l7vs_conn*)removeconn_list->data;
1256                 if( d == tmp_conn->dest ){
1257                         l7vs_conn_destroy( tmp_conn );
1258                 }
1259                 removeconn_list = g_list_remove( removeconn_list, tmp_conn );
1260         } 
1261
1262         srv->dest_list = g_list_remove(srv->dest_list, d);
1263         l7vs_dest_destroy(d);
1264
1265         //DEBUG output
1266         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1267                 char    debugstr[DEBUG_STR_LEN];
1268                 memset( debugstr, 0, DEBUG_STR_LEN );
1269                 sprintf( debugstr, "function l7vs_service_remove_dest(struct l7vs_service *srv, struct l7vs_dest_arg *darg) return : 0" );
1270                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,67, debugstr );
1271         }
1272
1273         return 0;
1274 }
1275
1276 /*!
1277  * schedule dest on con.(not use)
1278  * @param[in] *srv      service pointer
1279  * @param[in] *conn     l7vs_conn pointer
1280  * @return              success = 0 false = -1
1281  */
1282 int
1283 l7vs_service_schedule(struct l7vs_service *srv, 
1284                       struct l7vs_conn *conn)
1285 {
1286         struct l7vs_dest *dest;
1287
1288         if( NULL == srv || NULL == conn || NULL == srv->scheduler ){
1289                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,21, "Service / lookup schedule-module : Invalid argument" );
1290                 return -1;
1291         }
1292
1293         dest = srv->scheduler->schedule(srv, conn);
1294         if (dest == NULL) {
1295                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SCHEDULE,1, "no real server defined" );
1296                 return -1;
1297         }
1298
1299         return l7vs_conn_connect_rs(conn, dest);
1300 }
1301
1302
1303 /*!
1304  * NOP
1305  */
1306 int
1307 l7vs_service_establish(struct l7vs_service *srv, 
1308                        struct l7vs_conn *conn)
1309 {
1310         return 0;
1311 }
1312
1313 /*!
1314  * connection list append conn in service
1315  * @param[in]   *srv    service pointer
1316  * @param[in]   *conn   l7vs_conn pointer
1317  * @return      void
1318  */
1319 int
1320 l7vs_service_register_conn(struct l7vs_service *srv,
1321                            struct l7vs_conn *conn)
1322 {
1323         if( NULL == srv || NULL == conn ){
1324                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,22, "register connection : Invalid argument" );
1325                 return -1;
1326         }
1327
1328         //DEBUG output
1329         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1330                 char    debugstr[DEBUG_STR_LEN];
1331                 char    connstr[DEBUG_STR_LEN];
1332                 memset( debugstr, 0, DEBUG_STR_LEN );
1333                 sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn)" );
1334                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,68, debugstr );
1335                 memset( debugstr, 0, DEBUG_STR_LEN );
1336                 sprintf( debugstr, "srv dump" );
1337                 l7vs_service_c_str( debugstr, srv );
1338                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,69, debugstr );
1339                 memset( debugstr, 0, DEBUG_STR_LEN );
1340                 memset( connstr, 0, DEBUG_STR_LEN );
1341                 l7vs_conn_c_str( connstr, conn );
1342                 sprintf( debugstr, "conn dump %s", connstr );
1343                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,70, debugstr );
1344         }
1345
1346         if( NULL != g_hash_table_lookup( srv->conn_hash, &conn->ciom->fd ) ){
1347                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,5, "register connection : conflict connection." );
1348                 //DEBUG output
1349                 if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1350                         char    debugstr[DEBUG_STR_LEN];
1351                         memset( debugstr, 0, DEBUG_STR_LEN );
1352                         sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : -1" );
1353                         LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,71, debugstr );
1354                 }
1355                 return -1;
1356         }
1357
1358         g_hash_table_insert( srv->conn_hash, &conn->ciom->fd, conn );
1359         //DEBUG output
1360         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1361                 char    debugstr[DEBUG_STR_LEN];
1362                 memset( debugstr, 0, DEBUG_STR_LEN );
1363                 sprintf( debugstr, "function l7vs_service_register_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : 0" );
1364                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,72, debugstr );
1365         }
1366         return 0;
1367 }
1368
1369 /*!
1370  * connection list delete con in service
1371  * @param[in]   *srv    service pointer
1372  * @param[in]   *conn   l7vs_conn pointer
1373  * @return              void
1374  */
1375 int
1376 l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn)
1377 {
1378         if( NULL == srv || NULL == conn ){
1379                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,23, "remove connection : Invalid argument" );
1380                 return -1;
1381         }
1382
1383         //DEBUG output
1384         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1385                 char    debugstr[DEBUG_STR_LEN];
1386                 char    connstr[DEBUG_STR_LEN];
1387                 memset( debugstr, 0, DEBUG_STR_LEN );
1388                 sprintf( debugstr, "function l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn)" );
1389                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,73, debugstr );
1390                 memset( debugstr, 0, DEBUG_STR_LEN );
1391                 sprintf( debugstr, "srv dump" );
1392                 l7vs_service_c_str( debugstr, srv );
1393                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,74, debugstr );
1394                 memset( debugstr, 0, DEBUG_STR_LEN );
1395                 memset( connstr, 0, DEBUG_STR_LEN );
1396                 l7vs_conn_c_str( connstr, conn );
1397                 sprintf( debugstr, "conn dump %s", connstr );
1398                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,75, debugstr );
1399         }
1400
1401         g_hash_table_remove( srv->conn_hash, &conn->ciom->fd );
1402         //DEBUG output
1403         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1404                 char    debugstr[DEBUG_STR_LEN];
1405                 memset( debugstr, 0, DEBUG_STR_LEN );
1406                 sprintf( debugstr, "function l7vs_service_remove_conn(struct l7vs_service *srv, struct l7vs_conn *conn) return : 0" );
1407                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,76, debugstr );
1408         }
1409         return 0;
1410 }
1411
1412 /*!
1413  * destroy all member in all service.
1414  *
1415  */
1416 void
1417 l7vs_service_flush_all(void)
1418 {
1419         GList *l;
1420         struct l7vs_service *srv;
1421
1422         //DEBUG output
1423         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1424                 char    debugstr[DEBUG_STR_LEN];
1425                 memset( debugstr, 0, DEBUG_STR_LEN );
1426                 sprintf( debugstr, "function l7vs_service_flush_all()" );
1427                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,77, debugstr );
1428         }
1429
1430         while ((l = g_list_first(l7vs_service_list)) != NULL) {
1431                 srv = (struct l7vs_service *)l->data;
1432                 l7vs_service_destroy( srv );
1433         }
1434         //DEBUG output
1435         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1436                 char    debugstr[DEBUG_STR_LEN];
1437                 memset( debugstr, 0, DEBUG_STR_LEN );
1438                 sprintf( debugstr, "function l7vs_service_flush_all() return" );
1439                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,78, debugstr );
1440         }
1441 }
1442
1443 /*!
1444  * set QoS(TraficControl) Threshold value
1445  * @param[in]   *srv    service pointer
1446  * @param[in]   *arg    l7vs_service_arg_multi pointer
1447  * return               0 = success / -1 = failur
1448  */
1449 int
1450 l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )
1451 {
1452 //      struct l7vs_service_repdata *   service_replicationdata;
1453
1454         if( NULL == srv ){
1455                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,24, "Argument srv is NULL" );
1456                 return -1;
1457         }
1458         if( NULL == arg ){
1459                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,25, "Argument arg is NULL" );
1460                 return -1;
1461         }
1462
1463         //DEBUG output
1464         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1465                 char    debugstr[DEBUG_STR_LEN];
1466                 memset( debugstr, 0, DEBUG_STR_LEN );
1467                 sprintf( debugstr, "function l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )" );
1468                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,79, debugstr );
1469                 memset( debugstr, 0, DEBUG_STR_LEN );
1470                 sprintf( debugstr, "srv dump" );
1471                 l7vs_service_c_str( debugstr, srv );
1472                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,80, debugstr );
1473                 memset( debugstr, 0, DEBUG_STR_LEN );
1474                 sprintf( debugstr, "arg dump" );
1475                 l7vs_service_arg_multi_c_str( debugstr, arg );
1476                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,81, debugstr );
1477         }
1478
1479         srv->qos_threshold_up   = arg->srv_arg.qos_threshold_up;
1480         srv->qos_threshold_down = arg->srv_arg.qos_threshold_down;
1481
1482         // Get the replication area.
1483         unsigned int r_size = 0;
1484         l7vs_service_repdata * repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory( REP_COMP_SV, &r_size );
1485         // make replication data
1486         if( NULL != repdata )make_replication_data( rep_size_num, repdata );
1487
1488         //DEBUG output
1489         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1490                 char    debugstr[DEBUG_STR_LEN];
1491                 memset( debugstr, 0, DEBUG_STR_LEN );
1492                 sprintf( debugstr, "function l7vs_service_set_QoS_Threshold( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg ) return : 0" );
1493                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,82, debugstr );
1494         }
1495
1496         return 0;
1497 }
1498
1499 /*!
1500  * set Sorry-Server values
1501  * @param[in]   *srv    service pointer
1502  * @param[in]   *arg    l7vs_service_arg_multi pointer
1503  * return               0 = success / -1 = failure
1504  */
1505 int
1506 l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )
1507 {
1508         struct sockaddr_in * saddr;
1509 //      struct l7vs_service_repdata *   service_replicationdata;
1510
1511         if( NULL == srv ){
1512                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,26, "Argument srv is NULL" );
1513                 return -1;
1514         }
1515         if( NULL == arg ){
1516                 LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_PROGRAM,27, "Argument arg is NULL" );
1517                 return -1;
1518         }
1519         //DEBUG output
1520         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1521                 char    debugstr[DEBUG_STR_LEN];
1522                 memset( debugstr, 0, DEBUG_STR_LEN );
1523                 sprintf( debugstr, "function l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg )" );
1524                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,83, debugstr );
1525                 memset( debugstr, 0, DEBUG_STR_LEN );
1526                 sprintf( debugstr, "srv dump" );
1527                 l7vs_service_c_str( debugstr, srv );
1528                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,84, debugstr );
1529                 memset( debugstr, 0, DEBUG_STR_LEN );
1530                 sprintf( debugstr, "arg dump" );
1531                 l7vs_service_arg_multi_c_str( debugstr, arg );
1532                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,85, debugstr );
1533         }
1534         // set sorry data
1535         saddr = (struct sockaddr_in *)&arg->srv_arg.sorry_addr;
1536         srv->sorry_dest->addr   = *saddr;
1537         srv->sorry_cc   = arg->srv_arg.sorry_cc;
1538         srv->sorry_flag = arg->srv_arg.sorry_flag;
1539
1540         unsigned int r_size = 0;
1541         l7vs_service_repdata *repdata = (l7vs_service_repdata*)l7vs_replication_pay_memory(REP_COMP_SV, &r_size);
1542
1543         //make replication data
1544         if( NULL != repdata)
1545         {
1546                 make_replication_data(rep_size_num, repdata);
1547         }
1548
1549         //DEBUG output
1550         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1551                 char    debugstr[DEBUG_STR_LEN];
1552                 memset( debugstr, 0, DEBUG_STR_LEN );
1553                 sprintf( debugstr, "function l7vs_service_set_SorryServer_Values( struct l7vs_service * srv, struct l7vs_service_arg_multi * arg ) return : 0" );
1554                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,86, debugstr );
1555         }
1556
1557         return 0;
1558 }
1559
1560 /*!
1561  * get number of l7vs_service list
1562  * @param[in]   none
1563  * @return      unsigned int
1564  */
1565 unsigned int
1566 l7vs_service_get_VSnum()
1567 {
1568         int     retval  = g_list_length( l7vs_service_list );
1569         //DEBUG output
1570         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1571                 char    debugstr[DEBUG_STR_LEN];
1572                 memset( debugstr, 0, DEBUG_STR_LEN );
1573                 sprintf( debugstr, "function l7vs_service_get_VSnum()" );
1574                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,87, debugstr );
1575                 memset( debugstr, 0, DEBUG_STR_LEN );
1576                 sprintf( debugstr, "function l7vs_service_get_VSnum() return : num = retval" );
1577                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,88, debugstr );
1578         }
1579         return  retval;
1580 }
1581
1582 /*!
1583  * find and get l7vs_service by number of l7vs_service_list
1584  * @param[in]   num     number of l7vs_service list
1585  * return       l7vs_service pointer
1586  */
1587 struct l7vs_service *
1588 l7vs_service_get_VSInfo_byNum( unsigned int num )
1589 {
1590         unsigned int vs_num = g_list_length( l7vs_service_list );
1591         if( 0 > num )return NULL;
1592         if( 0 == vs_num )return NULL;
1593         //DEBUG output
1594         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1595                 char    debugstr[DEBUG_STR_LEN];
1596                 memset( debugstr, 0, DEBUG_STR_LEN );
1597                 sprintf( debugstr, "function l7vs_service_get_VSInfo_byNum( unsigned int num )" );
1598                 sprintf( debugstr, "%s num = %d", debugstr, num );
1599                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,89, debugstr );
1600                 memset( debugstr, 0, DEBUG_STR_LEN );
1601                 sprintf( debugstr, "function l7vs_service_get_VSInfo_byNum( unsigned int num ) return" );
1602                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,90, debugstr );
1603         }
1604         return (struct l7vs_service *)g_list_nth_data( l7vs_service_list, num );
1605 }
1606
1607 /*!
1608  * find and get l7vs_service by service-handle
1609  * @param[in]   in_handle       l7vs_service handle
1610  * return       l7vs_service pointer
1611  */
1612 struct l7vs_service *
1613 l7vs_service_get_VSInfo_byHandler( handle_t in_handle )
1614 {
1615         GList * l;
1616         //DEBUG output
1617         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1618                 char    debugstr[DEBUG_STR_LEN];
1619                 memset( debugstr, 0, DEBUG_STR_LEN );
1620                 sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle )" );
1621                 sprintf( debugstr, "%s, in_handle = %d", debugstr, in_handle );
1622                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,91, debugstr );
1623         }
1624         for ( l = g_list_first(l7vs_service_list); l != NULL; l = g_list_next(l) ){
1625                 if( ((struct l7vs_service *)l->data)->handle == in_handle ){
1626                         //DEBUG output
1627                         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1628                                 char    debugstr[DEBUG_STR_LEN];
1629                                 memset( debugstr, 0, DEBUG_STR_LEN );
1630                                 sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle ) return" );
1631                                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,92, debugstr );
1632                         }
1633                         return (struct l7vs_service *)l->data;
1634                 }
1635         }
1636         //DEBUG output
1637         if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){
1638                 char    debugstr[DEBUG_STR_LEN];
1639                 memset( debugstr, 0, DEBUG_STR_LEN );
1640                 sprintf( debugstr, "function l7vs_service_get_VSInfo_byHandler( handle_t in_handle ) return : NULL" );
1641                 LOGGER_PUT_LOG_DEBUG( LOG_CAT_L7VSD_VIRTUAL_SERVICE,93, debugstr );
1642                         }
1643         return  NULL;
1644 }
1645
1646 void
1647 l7vs_service_update_throughput( struct l7vs_service* srv, unsigned long long current_time ) {
1648         if ( LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK_BANDWIDTH) ) {
1649                 char    srv_str[DEBUG_STR_LEN];
1650                 memset( srv_str, 0, DEBUG_STR_LEN );
1651         l7vs_service_c_str(srv_str, srv);
1652                 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);
1653         }
1654     if (srv->pre_recvtime_from_client == current_time - 2) {
1655         srv->pre_recvtime_from_client = current_time - 1;
1656         srv->pre_recvsize_from_client = srv->cur_recvsize_from_client;
1657         srv->cur_recvsize_from_client = 0;
1658     }
1659     else if (srv->pre_recvtime_from_client != current_time - 1) {
1660         srv->pre_recvtime_from_client = current_time - 1;
1661         srv->pre_recvsize_from_client = 0;
1662         srv->cur_recvsize_from_client = 0;
1663     }
1664     if (srv->pre_recvtime_from_server == current_time - 2) {
1665         srv->pre_recvtime_from_server = current_time - 1;
1666         srv->pre_recvsize_from_server = srv->cur_recvsize_from_server;
1667         srv->cur_recvsize_from_server = 0;
1668     }
1669     else if (srv->pre_recvtime_from_server != current_time - 1) {
1670         srv->pre_recvtime_from_server = current_time - 1;
1671         srv->pre_recvsize_from_server = 0;
1672         srv->cur_recvsize_from_server = 0;
1673     }
1674         if ( LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK_BANDWIDTH) ) {
1675                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_VIRTUAL_SERVICE,98,"out_function: void l7vs_service_update_throughput(struct l7vs_service* srv, unsigned long long current_time)");
1676         }
1677 }