OSDN Git Service

4b74ddb7204f2190135c509d6096f5bc4580d35e
[ultramonkey-l7/ultramonkey-l7-v2.git] / src / conn.c
1 /*
2  * @file  conn.c
3  * @brief the connection management component
4  * @brief transmit data between client and realserver
5  * @brief and calls protocol module to decide realserver
6  * @brief also modify realserver data
7  *
8  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
9  * Copyright (C) 2005  NTT COMWARE Corporation.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  * 02110-1301 USA
25  *
26  **********************************************************************/
27
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/select.h>
31 #include <sys/time.h>
32 #include <netinet/in.h>
33 #include <netinet/tcp.h>
34 #include <arpa/inet.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <assert.h>
39 #include <glib.h>
40 #include <limits.h>
41 #include <errno.h>
42 #include "logger_wrapper.h"
43 #include "l7vs_config.h"
44 #include "l7vs_iomuxlist.h"
45 #include "l7vs_lsock.h"
46 #include "l7vs_conn.h"
47 #include "l7vs_service.h"
48 #include "l7vs.h"
49 #include "l7vs_module.h"
50 #include "l7vs_sched.h"
51
52 static int l7vs_conn_cl_callback(struct l7vs_iomux*);
53 static int l7vs_conn_client_receiving(struct l7vs_iomux*);
54 static int l7vs_conn_is_rs_connected(struct l7vs_iomux*, struct l7vs_conn*, struct l7vs_service**, struct l7vs_dest**);
55 static int l7vs_conn_connection_establish(struct l7vs_iomux*, struct l7vs_conn*, struct l7vs_service*, struct l7vs_dest*);
56 static int l7vs_conn_block(struct l7vs_iomux*, struct l7vs_iomux*);
57 static int l7vs_conn_busy(struct l7vs_iomux*);
58 static int l7vs_conn_sending(struct l7vs_iomux*, struct l7vs_iomux*);
59 static int l7vs_conn_sent_next_state(struct l7vs_iomux*, struct l7vs_iomux*);
60 static int l7vs_conn_rs_callback(struct l7vs_iomux* );
61 static int l7vs_conn_realserver_receiving(struct l7vs_iomux*);
62 static int l7vs_conn_realserver_modify_data(struct l7vs_iomux*);
63 static int l7vs_conn_recv(struct l7vs_iomux*, int);
64 static int l7vs_conn_preread(struct l7vs_iomux*, int);
65 static int l7vs_conn_send(struct l7vs_iomux*, int);
66 static int l7vs_conn_change_connect_rs(struct l7vs_conn*, struct l7vs_dest*);
67 static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction );
68 static void l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize, int direction );
69 static void l7vs_conn_dump_data(char* str_data, const char* data, const size_t len);
70 static int l7vs_conn_read_bufsize = 20480;              //! conn read buffer size
71 static int throughput_interval = BPS_DEFAULT_INTERVAL;  //! throughput interval
72
73 int
74 l7vs_conn_init(void)
75 {
76     /*-------- DEBUG LOG --------*/
77     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
78         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,341,
79             "in_function: int lvs_conn_init() ");
80     }
81     /*------ DEBUG LOG END ------*/
82
83     int ret = parameter_is_int_exist( PARAM_COMP_CONN, "read_bufsize" );
84     if (ret) {
85         int bufsize = parameter_get_int_value( PARAM_COMP_CONN, "read_bufsize" );
86         if (bufsize >= L7VS_CONN_READ_BUFSIZE_MIN && bufsize <= L7VS_CONN_READ_BUFSIZE_MAX)
87             l7vs_conn_read_bufsize = bufsize;
88 //            LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK,5,
89 //                "l7vsd uses read_bufsize = %d ",bufsize);
90         else if (bufsize > L7VS_CONN_READ_BUFSIZE_MAX) {
91             l7vs_conn_read_bufsize = L7VS_CONN_READ_BUFSIZE_MAX;
92             LOGGER_PUT_LOG_WARN(LOG_CAT_L7VSD_NETWORK,1,
93                 "Your read_bufsize is over maximum size. l7vsd uses maximum read_bufsize = %d instead ",L7VS_CONN_READ_BUFSIZE_MAX);
94         }
95         else {
96             l7vs_conn_read_bufsize = L7VS_CONN_READ_BUFSIZE_MIN;
97             LOGGER_PUT_LOG_WARN(LOG_CAT_L7VSD_NETWORK,2,
98                 "Your read_bufsize is under minimum size. l7vsd uses minimum read_bufsize = %d instead ",L7VS_CONN_READ_BUFSIZE_MIN);
99         }
100     }
101     else {
102         LOGGER_PUT_LOG_WARN(LOG_CAT_L7VSD_NETWORK,3,
103             "read_bufsize is not specified. l7vsd uses default read_bufsize = %d ",l7vs_conn_read_bufsize);
104     }
105
106     if ( parameter_is_int_exist( PARAM_COMP_L7VSD, "calc_throughput_interval" ) ) {
107         throughput_interval = parameter_get_int_value( PARAM_COMP_L7VSD, "calc_throughput_interval" );
108     }
109
110     /*-------- DEBUG LOG --------*/
111     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
112         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,345,
113             "out_function: int lvs_conn_init() ");
114     }
115     /*------ DEBUG LOG END ------*/
116     return 1;
117 }
118
119 /*!
120  * dump data
121  *
122  * @param[out]  str_data    dump string
123  * @param[in]   data        source data
124  * @param[in]   len         source data length
125  * @return      void
126  */
127 void l7vs_conn_dump_data(char* str_data, const char* data, const size_t len)
128 {
129     if (!str_data) {
130         return;
131     }
132
133     if (!data) {
134         snprintf(str_data, DEBUG_STR_LEN, "(nil)");
135         return;
136     }
137
138     const char* table[] = {
139         "00 ", "01 ", "02 ", "03 ", "04 ", "05 ", "06 ", "07 ", "08 ", "09 ", "0a ", "0b ", "0c ", "0d ", "0e ", "0f ",
140         "10 ", "11 ", "12 ", "13 ", "14 ", "15 ", "16 ", "17 ", "18 ", "19 ", "1a ", "1b ", "1c ", "1d ", "1e ", "1f ",
141         "20 ", "21 ", "22 ", "23 ", "24 ", "25 ", "26 ", "27 ", "28 ", "29 ", "2a ", "2b ", "2c ", "2d ", "2e ", "2f ",
142         "30 ", "31 ", "32 ", "33 ", "34 ", "35 ", "36 ", "37 ", "38 ", "39 ", "3a ", "3b ", "3c ", "3d ", "3e ", "3f ",
143         "40 ", "41 ", "42 ", "43 ", "44 ", "45 ", "46 ", "47 ", "48 ", "49 ", "4a ", "4b ", "4c ", "4d ", "4e ", "4f ",
144         "50 ", "51 ", "52 ", "53 ", "54 ", "55 ", "56 ", "57 ", "58 ", "59 ", "5a ", "5b ", "5c ", "5d ", "5e ", "5f ",
145         "60 ", "61 ", "62 ", "63 ", "64 ", "65 ", "66 ", "67 ", "68 ", "69 ", "6a ", "6b ", "6c ", "6d ", "6e ", "6f ",
146         "70 ", "71 ", "72 ", "73 ", "74 ", "75 ", "76 ", "77 ", "78 ", "79 ", "7a ", "7b ", "7c ", "7d ", "7e ", "7f ",
147         "80 ", "81 ", "82 ", "83 ", "84 ", "85 ", "86 ", "87 ", "88 ", "89 ", "8a ", "8b ", "8c ", "8d ", "8e ", "8f ",
148         "90 ", "91 ", "92 ", "93 ", "94 ", "95 ", "96 ", "97 ", "98 ", "99 ", "9a ", "9b ", "9c ", "9d ", "9e ", "9f ",
149         "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "a6 ", "a7 ", "a8 ", "a9 ", "aa ", "ab ", "ac ", "ad ", "ae ", "af ",
150         "b0 ", "b1 ", "b2 ", "b3 ", "b4 ", "b5 ", "b6 ", "b7 ", "b8 ", "b9 ", "ba ", "bb ", "bc ", "bd ", "be ", "bf ",
151         "c0 ", "c1 ", "c2 ", "c3 ", "c4 ", "c5 ", "c6 ", "c7 ", "c8 ", "c9 ", "ca ", "cb ", "cc ", "cd ", "ce ", "cf ",
152         "d0 ", "d1 ", "d2 ", "d3 ", "d4 ", "d5 ", "d6 ", "d7 ", "d8 ", "d9 ", "da ", "db ", "dc ", "dd ", "de ", "df ",
153         "e0 ", "e1 ", "e2 ", "e3 ", "e4 ", "e5 ", "e6 ", "e7 ", "e8 ", "e9 ", "ea ", "eb ", "ec ", "ed ", "ee ", "ef ",
154         "f0 ", "f1 ", "f2 ", "f3 ", "f4 ", "f5 ", "f6 ", "f7 ", "f8 ", "f9 ", "fa ", "fb ", "fc ", "fd ", "fe ", "ff "
155     };
156     const int hx_len = 3;
157
158     size_t pos = 0;
159     for (size_t i = 0; i < len; ++i) {
160         if (DEBUG_STR_LEN <= pos + hx_len) {
161             break;
162         }
163         strncpy(str_data + pos, table[(unsigned char)*(data + i)], hx_len);
164         pos += hx_len;
165     }
166     *(str_data + pos) = '\0';
167 }
168
169 /*!
170  * connection create
171  *
172  * @param[in]   lfd     listening socket fd
173  * @param[in]   lsock   listening socket
174  * @return      connection
175  */
176 struct l7vs_conn *
177 l7vs_conn_create(int lfd, struct l7vs_lsock *lsock)
178 {
179     /*-------- DEBUG LOG --------*/
180     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
181         char lsock_str[DEBUG_STR_LEN] = {0};
182         l7vs_lsock_c_str(lsock_str, lsock);
183         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,50,
184             "in_function: struct l7vs_conn* lvs_conn_create(int fd, struct l7vs_lsock *lsock) "
185             "lfd=%d: "
186             "lsock=%s",
187             lfd, lsock_str);
188     }
189     /*------ DEBUG LOG END ------*/
190
191         socklen_t len = 0;
192         struct l7vs_conn *conn = NULL;
193         int mss = 0;
194         int ret = 0;
195     int flags = 0;
196
197     if (-1 == lfd) {
198         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,28, "error / lsock fd is not specified");
199         goto create_error;
200     }
201
202     if (!lsock) {
203         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,29, "error / lsock is null");
204         goto create_error;
205     }
206        
207         conn = (struct l7vs_conn*)malloc(sizeof(struct l7vs_conn));
208         if (!conn) {
209         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,8, "error / can not allocate memory");
210         goto create_error;
211     }
212     /*-------- DEBUG LOG --------*/
213     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
214         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,51,
215             "malloc: conn=%p: size=%zu",
216             conn, sizeof(struct l7vs_conn));
217     }
218     /*------ DEBUG LOG END ------*/
219     memset(conn, 0, sizeof(struct l7vs_conn));
220
221     conn->ciom = l7vs_iomux_get_from_avail_list();
222     if (!conn->ciom) {
223         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,7, "error / can not get client iom");
224         goto create_error;
225     }
226     /*-------- DEBUG LOG --------*/
227     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
228         char ciom_str[DEBUG_STR_LEN] = {0};
229         l7vs_iomux_c_str(ciom_str, conn->ciom);
230         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,52,
231             "iom_get: conn->ciom=%s",
232             ciom_str);
233     }
234     /*------ DEBUG LOG END ------*/
235
236     conn->riom = l7vs_iomux_get_from_avail_list();
237     if (!conn->riom) {
238         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,8, "error / can not get realserver iom");
239         goto create_error;
240     }
241     /*-------- DEBUG LOG --------*/
242     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
243         char riom_str[DEBUG_STR_LEN] = {0};
244         l7vs_iomux_c_str(riom_str, conn->riom);
245         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,53,
246             "iom_get: conn->riom=%s",
247             riom_str);
248     }
249     /*------ DEBUG LOG END ------*/
250
251         conn->cldata_len = 0;
252         conn->cldata_bufsize = l7vs_conn_read_bufsize;
253         conn->cldata = (char *)malloc(conn->cldata_bufsize);
254         if (!conn->cldata) {
255         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,9, "error / can not allocate memory for buffer");
256         goto create_error;
257         }
258     /*-------- DEBUG LOG --------*/
259     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
260         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,54,
261             "malloc: conn->cldata=%p: size=%zu",
262             conn->cldata, conn->cldata_bufsize);
263     }
264     /*------ DEBUG LOG END ------*/
265     memset(conn->cldata, 0, conn->cldata_bufsize);
266
267         len = sizeof(struct sockaddr_in);
268     /*-------- DEBUG LOG --------*/
269     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
270         char caddr_str[DEBUG_STR_LEN] = {0};
271         l7vs_conn_sockaddr_in_c_str(caddr_str, &conn->caddr);
272         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,55,
273             "accept param: lfd=%d: conn->caddr=%s: len=%d",
274             lfd, caddr_str, len);
275     }
276     /*------ DEBUG LOG END ------*/
277         conn->ciom->fd = accept(lfd, (struct sockaddr *)&conn->caddr, &len);
278         if (conn->ciom->fd < 0) {
279         char caddr_str[DEBUG_STR_LEN] = {0};
280         l7vs_conn_sockaddr_in_c_str(caddr_str, &conn->caddr);
281         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,8,
282             "error / accept error accept param: lfd=%d: conn->caddr=%s: len=%d (%s)",
283             lfd, caddr_str, len,strerror(errno));
284         goto create_error;
285         }
286     /*-------- DEBUG LOG --------*/
287     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
288         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,56,
289             "accept result: conn->ciom->fd=%d",
290             conn->ciom->fd);
291     }
292     /*------ DEBUG LOG END ------*/
293
294     // get current flag
295     /*-------- DEBUG LOG --------*/
296     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
297         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,57,
298             "fnctl param: conn->ciom->fd=%d: cmd=F_GETFL: flags=0",
299             conn->ciom->fd);
300     }
301     /*------ DEBUG LOG END ------*/
302     flags = fcntl(conn->ciom->fd, F_GETFL, 0);
303     if (0 > flags) {
304         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,9,
305              "error / fcntl((conn->ciom->fd=%d),F_GETFL) error(%s)",
306              conn->ciom->fd,strerror(errno));
307         goto create_error;
308     }
309     /*-------- DEBUG LOG --------*/
310     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
311         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,58,
312             "fnctl result: flags=%d",
313             flags);
314     }
315     /*------ DEBUG LOG END ------*/
316
317     // set nonblocking
318     /*-------- DEBUG LOG --------*/
319     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
320         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,59,
321             "fnctl param: conn->ciom->fd=%d: cmd=F_SETFL: flags=%d",
322             conn->ciom->fd, (flags | O_NONBLOCK));
323     }
324     /*------ DEBUG LOG END ------*/
325     flags = fcntl(conn->ciom->fd, F_SETFL, flags | O_NONBLOCK);
326     if (0 > flags) {
327         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,10,
328             "error / fcntl((conn->ciom->fd=%d),F_SETFL) error(%s)",
329             conn->ciom->fd,strerror(errno));
330         goto create_error;
331     }
332     /*-------- DEBUG LOG --------*/
333     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
334         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,60,
335             "fnctl result: flags=%d",
336             flags);
337     }
338     /*------ DEBUG LOG END ------*/
339
340     // get client mss
341         len = sizeof(int);
342     /*-------- DEBUG LOG --------*/
343     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
344         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,61,
345             "getsockopt param: conn->ciom->fd=%d: level=IPROTO_TCP: optname=TCP_MAXSEG: "
346             "len=%d",
347             conn->ciom->fd, len);
348     }
349     /*------ DEBUG LOG END ------*/
350         ret = getsockopt(conn->ciom->fd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
351         if (0 > ret) {
352         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,11, "error / getsockopt TCP_MAXSEG error(%s)", strerror(errno));
353         goto create_error;
354         }
355     /*-------- DEBUG LOG --------*/
356     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
357         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,62,
358             "getsockopt result: mss=%d: len=%d",
359             mss, len);
360     }
361     /*------ DEBUG LOG END ------*/
362         conn->cmss = mss;
363     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
364         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,63, "client %s mss %d",
365             inet_ntoa(conn->caddr.sin_addr), mss);
366     }
367
368         conn->lsock = lsock;
369     /*-------- DEBUG LOG --------*/
370     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
371         char lsock_str[DEBUG_STR_LEN] = {0};
372         l7vs_lsock_c_str(lsock_str, lsock);
373         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,64,
374             "pointer_assign: conn->lsock=%s",
375             lsock_str);
376     }
377     /*------ DEBUG LOG END ------*/
378         conn->proto = lsock->proto;
379     /*-------- DEBUG LOG --------*/
380     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
381         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,65,
382             "conn->ciom->status change: %d->%d",
383             conn->ciom->status, iomux_conn_receiving);
384     }
385     /*------ DEBUG LOG END ------*/
386     conn->ciom->status = iomux_conn_receiving;
387     conn->ciom->callback = l7vs_conn_cl_callback;
388     /*-------- DEBUG LOG --------*/
389     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
390         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,66,
391             "pointer_assign: conn->ciom->callback=%p",
392             l7vs_conn_cl_callback);
393     }
394     /*------ DEBUG LOG END ------*/
395         conn->ciom->data = conn;
396     /*-------- DEBUG LOG --------*/
397     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
398         char conn_str[DEBUG_STR_LEN] = {0};
399         l7vs_conn_c_str(conn_str, conn);
400         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,67,
401             "pointer_assign: conn->ciom->data=%s",
402             conn_str);
403     }
404     /*------ DEBUG LOG END ------*/
405     conn->sorry_conn_flag = 0;
406     conn->old_dest = NULL;
407     l7vs_iomux_add(conn->ciom, iom_read);
408
409     // connect real server immediately if all lsock services are fast schedule.
410     if (lsock->fast_schedule) {
411         struct l7vs_service* srv;
412         struct l7vs_dest* dest;
413         conn->ciom->status = iomux_conn_received;
414         if (!l7vs_conn_is_rs_connected(conn->ciom, conn, &srv, &dest)) {
415             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,16, "error / is realserver connected failed");
416         }
417         else {
418             switch (conn->ciom->status) {
419             case iomux_conn_block:
420                 //already decided real server
421                 break;
422             case iomux_conn_service_selected:
423                 //service and destination were selected then attempt to connect the real server
424                 if (!l7vs_conn_connection_establish(conn->ciom, conn, srv, dest)) {
425                     LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,17, "error / client connect rs failed");
426                 }
427                 break;
428             default:
429                 //invalid status
430                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,34, "error / invalid status(%d)", conn->ciom->status);
431                 break;
432             }
433         }
434     }
435     /*-------- DEBUG LOG --------*/
436     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
437         char ret_conn_str[DEBUG_STR_LEN] = {0};
438         l7vs_conn_c_str(ret_conn_str, conn);
439         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,68,
440             "out_function: struct l7vs_conn* lvs_conn_create(int fd, struct l7vs_lsock *lsock) "
441             "return_value: conn=%s",
442             ret_conn_str);
443     }
444     /*------ DEBUG LOG END ------*/
445         return conn;
446
447 create_error:
448     /*-------- DEBUG LOG --------*/
449     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
450         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,69,
451             "entering: create_error_label");
452     }
453     /*------ DEBUG LOG END ------*/
454     if (conn) {
455         if (conn->ciom) {
456             if (-1 != conn->ciom->fd) {
457                 /*-------- DEBUG LOG --------*/
458                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
459                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,70,
460                         "close: conn->ciom->fd=%d",
461                         conn->ciom->fd);
462                 }
463                 /*------ DEBUG LOG END ------*/
464                 close(conn->ciom->fd);
465             }
466             /*-------- DEBUG LOG --------*/
467             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
468                 char put_ciom_str[DEBUG_STR_LEN] = {0};
469                 l7vs_iomux_c_str(put_ciom_str, conn->ciom);
470                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,71,
471                     "iom_put: conn->ciom=%s",
472                     put_ciom_str);
473             }
474             /*------ DEBUG LOG END ------*/
475             l7vs_iomux_put_to_avail_list(conn->ciom);
476         }
477         if (conn->riom) {
478             /*-------- DEBUG LOG --------*/
479             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
480                 char put_riom_str[DEBUG_STR_LEN] = {0};
481                 l7vs_iomux_c_str(put_riom_str, conn->riom);
482                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,72,
483                     "iom_put: conn->riom=%s",
484                     put_riom_str);
485             }
486             /*------ DEBUG LOG END ------*/
487             l7vs_iomux_put_to_avail_list(conn->riom);
488         }
489         if (conn->cldata) {
490             /*-------- DEBUG LOG --------*/
491             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
492                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,73,
493                     "free: conn->cldata=%p",
494                     conn->cldata);
495             }
496             /*------ DEBUG LOG END ------*/
497             free(conn->cldata);
498         }
499         /*-------- DEBUG LOG --------*/
500         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
501             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,74,
502                 "free: conn=%p",
503                 conn);
504         }
505         /*------ DEBUG LOG END ------*/
506         free(conn);
507     }
508     /*-------- DEBUG LOG --------*/
509     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
510         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,75,
511             "out_function: struct l7vs_conn* lvs_conn_create(int fd, struct l7vs_lsock *lsock) "
512             "return_value: conn=NULL");
513     }
514     /*------ DEBUG LOG END ------*/
515     return NULL;
516 }
517
518 /*!
519  * connection destroy
520  *
521  * @param[in]   conn    connection
522  * @return      void
523  */
524 void
525 l7vs_conn_destroy(struct l7vs_conn *conn)
526 {
527     /*-------- DEBUG LOG --------*/
528     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
529         char conn_str[DEBUG_STR_LEN] = {0};
530         l7vs_conn_c_str(conn_str, conn);
531         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,76,
532             "in_function: void l7vs_conn_destroy(struct l7vs_conn *conn) "
533             "conn=%s",
534             conn_str);
535     }
536     /*------ DEBUG LOG END ------*/
537     if (!conn) {
538         /*-------- DEBUG LOG --------*/
539         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
540             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,77,
541                 "out_function: void l7vs_conn_destroy(struct l7vs_conn *conn) "
542                 "return_value: void");
543         }
544         /*------ DEBUG LOG END ------*/
545         return;
546     }
547
548     if (conn->srv) {
549         l7vs_service_remove_conn(conn->srv, conn);
550         /*-------- DEBUG LOG --------*/
551         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
552             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,78,
553                 "pointer_assign: conn->srv=NULL");
554         }
555         /*------ DEBUG LOG END ------*/
556         conn->srv = NULL;
557     }
558
559     if (conn->ciom) {
560         if (-1 != conn->ciom->fd) {
561             l7vs_conn_close_csock(conn);
562         }
563         /*-------- DEBUG LOG --------*/
564         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
565             char put_ciom_str[DEBUG_STR_LEN] = {0};
566             l7vs_iomux_c_str(put_ciom_str, conn->ciom);
567             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,79,
568                 "iom_put: conn->ciom=%s",
569                 put_ciom_str);
570         }
571         /*------ DEBUG LOG END ------*/
572         l7vs_iomux_put_to_avail_list(conn->ciom);
573         /*-------- DEBUG LOG --------*/
574         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
575             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,80,
576                 "pointer_assign: conn->ciom=NULL");
577         }
578         /*------ DEBUG LOG END ------*/
579         conn->ciom = NULL;
580     }
581
582     if (conn->riom) {
583         if (-1 != conn->riom->fd) {
584             l7vs_conn_close_rsock(conn);
585         }
586         /*-------- DEBUG LOG --------*/
587         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
588             char put_riom_str[DEBUG_STR_LEN] = {0};
589             l7vs_iomux_c_str(put_riom_str, conn->riom);
590             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,81,
591                 "iom_put: conn->riom=%s",
592                 put_riom_str);
593         }
594         /*------ DEBUG LOG END ------*/
595         l7vs_iomux_put_to_avail_list(conn->riom);
596         /*-------- DEBUG LOG --------*/
597         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
598             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,82,
599                 "pointer_assign: conn->riom=NULL");
600         }
601         /*------ DEBUG LOG END ------*/
602         conn->riom = NULL;
603     }
604
605     if (conn->cldata) {
606         /*-------- DEBUG LOG --------*/
607         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
608             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,83,
609                 "free: conn->cldata=%p",
610                 conn->cldata);
611         }
612         /*------ DEBUG LOG END ------*/
613         free(conn->cldata);
614         /*-------- DEBUG LOG --------*/
615         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
616             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,84,
617                 "pointer_assign: conn->cldata=NULL");
618         }
619         /*------ DEBUG LOG END ------*/
620         conn->cldata = NULL;
621     }
622
623     /*-------- DEBUG LOG --------*/
624     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
625         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,85,
626             "free: conn=%p",
627             conn);
628     }
629     /*------ DEBUG LOG END ------*/
630     free(conn);
631     /*-------- DEBUG LOG --------*/
632     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
633         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,86,
634             "out_function: void l7vs_conn_destroy(struct l7vs_conn *conn) "
635             "return_value: void");
636     }
637     /*------ DEBUG LOG END ------*/
638 }
639
640 /*!
641  * client connection callback
642  *
643  * @param[in]   iom     connection iomux
644  * @return      status
645  * @retval      0       failed
646  * @retval      1       succeed
647  */
648 static int
649 l7vs_conn_cl_callback(struct l7vs_iomux *iom )
650 {
651     /*-------- DEBUG LOG --------*/
652     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
653         char iom_str[DEBUG_STR_LEN] = {0};
654         l7vs_iomux_c_str(iom_str, iom);
655         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,87,
656             "in_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
657             "iom=%s",
658             iom_str);
659     }
660     /*------ DEBUG LOG END ------*/
661     struct l7vs_conn* conn = NULL;
662
663     if (!iom) {
664         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,30, "error / iom is null");
665         /*-------- DEBUG LOG --------*/
666         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
667             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,88,
668                 "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
669                 "return_value: 0");
670         }
671         /*------ DEBUG LOG END ------*/
672         return 0;
673     }
674
675     conn = (struct l7vs_conn *)iom->data;
676     /*-------- DEBUG LOG --------*/
677     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
678         char conn_str[DEBUG_STR_LEN] = {0};
679         l7vs_conn_c_str(conn_str, conn);
680         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,89,
681             "pointer_assign: conn=%s",
682             conn_str);
683     }
684     /*------ DEBUG LOG END ------*/
685
686     // invalid status check
687     if (iomux_conn_receiving != iom->status &&
688         iomux_conn_block != iom->status &&
689         iomux_conn_busy != iom->status && 
690         iomux_conn_sending != iom->status && 
691         iomux_conn_sending_busy != iom->status) {
692         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,31, "error / invalid status(%d)", iom->status);
693         l7vs_conn_destroy(conn);
694         /*-------- DEBUG LOG --------*/
695         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
696             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,90,
697                 "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
698                 "return_value: 0");
699         }
700         /*------ DEBUG LOG END ------*/
701         return 0;
702     }
703
704     // switch by current status
705     switch (iom->status) {
706     case iomux_conn_receiving:
707         if (!l7vs_conn_client_receiving(iom)) {
708             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,9, "error / cl_callback/client receiving failed");
709             l7vs_conn_destroy(conn);
710             /*-------- DEBUG LOG --------*/
711             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
712                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,91,
713                     "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
714                     "return_value: 0");
715             }
716             /*------ DEBUG LOG END ------*/
717             return 0;
718         }
719         if (iomux_conn_disconnected == iom->status) {
720             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
721                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,92, "client connection disconnected");
722             }
723             l7vs_conn_destroy(conn);
724         }
725         break;
726     case iomux_conn_block:
727         if (!l7vs_conn_block(iom, conn->riom)) {
728             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,10, "error / cl_callback/block failed");
729             l7vs_conn_destroy(conn);
730             /*-------- DEBUG LOG --------*/
731             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
732                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,93,
733                     "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
734                     "return_value: 0");
735             }
736             /*------ DEBUG LOG END ------*/
737             return 0;
738         }
739         break;
740     case iomux_conn_busy:
741         if (!l7vs_conn_busy(iom)) {
742             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,11, "error / cl_callback/busy failed");
743             l7vs_conn_destroy(conn);
744             /*-------- DEBUG LOG --------*/
745             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
746                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,94,
747                     "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
748                     "return_value: 0");
749             }
750             /*------ DEBUG LOG END ------*/
751             return 0;
752         }
753         break;
754     case iomux_conn_sending:
755         if (!l7vs_conn_sending(iom, conn->riom)) {
756             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,12, "error / cl_callback/sending failed");
757             l7vs_conn_destroy(conn);
758             /*-------- DEBUG LOG --------*/
759             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
760                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,95,
761                     "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
762                     "return_value: 0");
763             }
764             /*------ DEBUG LOG END ------*/
765             return 0;
766         }
767         break;
768     case iomux_conn_sending_busy:
769         if (!l7vs_conn_sending(iom, conn->riom)) {
770             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,13, "error / cl_callback/sending_busy failed");
771             l7vs_conn_destroy(conn);
772             /*-------- DEBUG LOG --------*/
773             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
774                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,96,
775                     "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
776                     "return_value: 0");
777             }
778             /*------ DEBUG LOG END ------*/
779             return 0;
780         }
781         break;
782     default:
783         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,14, "error / invalid status(%d)", iom->status);
784         l7vs_conn_destroy(conn);
785         /*-------- DEBUG LOG --------*/
786         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
787             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,97,
788                 "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
789                 "return_value: 0");
790         }
791         /*------ DEBUG LOG END ------*/
792         return 0;
793     }
794
795     /*-------- DEBUG LOG --------*/
796     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
797         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,98,
798             "out_function: static int l7vs_conn_cl_callback(struct l7vs_iomux *iom ) "
799             "return_value: 1");
800     }
801     /*------ DEBUG LOG END ------*/
802     return 1;
803 }
804
805 /*!
806  * client receiving
807  *
808  * @param[in]   iom     connection iomux
809  * @return      status
810  * @retval      0       failed
811  * @retval      1       succeed
812  */
813 static int
814 l7vs_conn_client_receiving(struct l7vs_iomux *iom)
815 {
816     /*-------- DEBUG LOG --------*/
817     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
818         char iom_str[DEBUG_STR_LEN] = {0};
819         l7vs_iomux_c_str(iom_str, iom);
820         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,99,
821             "in_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
822             "iom=%s",
823             iom_str);
824     }
825     /*------ DEBUG LOG END ------*/
826     struct l7vs_conn *conn = NULL;
827         struct l7vs_service *srv = NULL;
828         struct l7vs_dest *dest = NULL;
829
830     if (!iom) {
831         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,32, "error / iom is null");
832         /*-------- DEBUG LOG --------*/
833         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
834             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,100,
835                 "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
836                 "return_value: 0");
837         }
838         /*------ DEBUG LOG END ------*/
839         return 0;
840     }
841
842     if (iomux_conn_receiving != iom->status) {
843         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,33, "error / invalid status(%d)", iom->status);
844         /*-------- DEBUG LOG --------*/
845         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
846             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,101,
847                 "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
848                 "return_value: 0");
849         }
850         /*------ DEBUG LOG END ------*/
851         return 0;
852     }
853
854     conn = (struct l7vs_conn *)iom->data;
855     /*-------- DEBUG LOG --------*/
856     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
857         char conn_str[DEBUG_STR_LEN] = {0};
858         l7vs_conn_c_str(conn_str, conn);
859         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,102,
860             "pointer_assign: conn=%s",
861             conn_str);
862     }
863     /*------ DEBUG LOG END ------*/
864
865     // when the real server is not set in read-blocked
866     if (iomux_conn_block != conn->riom->status && iomux_conn_busy != conn->riom->status) {
867         // set the real server in read-blocked
868         /*-------- DEBUG LOG --------*/
869         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
870             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,103,
871                 "conn->riom->status change: %d->%d",
872                 conn->riom->status, iomux_conn_block);
873         }
874         /*------ DEBUG LOG END ------*/
875         conn->riom->status = iomux_conn_block;
876     }
877
878     // receive client data
879     if (!l7vs_conn_recv(iom, iom->fd)) {
880         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,15, "error / recv failed");
881         /*-------- DEBUG LOG --------*/
882         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
883             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,104,
884                 "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
885                 "return_value: 0");
886         }
887         /*------ DEBUG LOG END ------*/
888         return 0;
889     }
890     switch (iom->status) {
891     case iomux_conn_receiving:
892         // data still remain, epoll re-registration for read
893         l7vs_iomux_mod(iom, iom_read);
894         break;
895     case iomux_conn_received:
896         // all data is received, service is selected by using the received data
897         if (!l7vs_conn_is_rs_connected(iom, conn, &srv, &dest)) {
898             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,16, "error / is realserver connected failed");
899             /*-------- DEBUG LOG --------*/
900             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
901                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,105,
902                     "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
903                     "return_value: 0");
904             }
905             /*------ DEBUG LOG END ------*/
906             return 0;
907         }
908         switch (iom->status) {
909         case iomux_conn_block:
910             //already decided real server
911             /*-------- DEBUG LOG --------*/
912             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
913                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,106,
914                     "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
915                     "return_value: 1");
916             }
917             /*------ DEBUG LOG END ------*/
918             return 1;
919         case iomux_conn_service_selected:
920             //service and destination were selected then attempt to connect the real server
921             if (!l7vs_conn_connection_establish(iom, conn, srv, dest)) {
922                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,17, "error / client connect rs failed");
923                 /*-------- DEBUG LOG --------*/
924                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
925                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,107,
926                         "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
927                         "return_value: 0");
928                 }
929                 /*------ DEBUG LOG END ------*/
930                 return 0;
931             }
932             l7vs_conn_QoS_recvsize_register( conn, conn->cldata_len, QOS_UP );
933             break;
934         default:
935             //invalid status
936             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,34, "error / invalid status(%d)", iom->status);
937             /*-------- DEBUG LOG --------*/
938             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
939                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,108,
940                     "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
941                     "return_value: 0");
942             }
943             /*------ DEBUG LOG END ------*/
944             return 0;
945         }
946         break;
947     case iomux_conn_disconnected:
948         // client connection was disconnected
949         break;
950     default:
951         //invalid status
952         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,35, "error / invalid status(%d)", iom->status);
953         /*-------- DEBUG LOG --------*/
954         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
955             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,109,
956                 "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
957                 "return_value: 0");
958         }
959         /*------ DEBUG LOG END ------*/
960         return 0;
961     }
962     /*-------- DEBUG LOG --------*/
963     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
964         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,110,
965             "out_function: static int l7vs_conn_client_receiving(struct l7vs_iomux *iom) "
966             "return_value: 1");
967     }
968     /*------ DEBUG LOG END ------*/
969     return 1;
970 }
971
972 /*!
973  * check realserver fd, and if real server not connected, call select_service function
974  *
975  * @param[in]   iom     connection_iomux
976  * @param[in]   conn    connection
977  * @param[out]  srv     service
978  * @param[out]  dest    destination(real server)
979  * @return      status
980  * @retval      0       failed
981  * @retval      1       succeed
982  */
983 static int
984 l7vs_conn_is_rs_connected(struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest)
985 {
986     /*-------- DEBUG LOG --------*/
987     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
988         char iom_str[DEBUG_STR_LEN] = {0};
989         char conn_str[DEBUG_STR_LEN] = {0};
990         char srv_str[DEBUG_STR_LEN] = {0};
991         char dest_str[DEBUG_STR_LEN] = {0};
992         l7vs_iomux_c_str(iom_str, iom);
993         l7vs_conn_c_str(conn_str, conn);
994         l7vs_service_c_str(srv_str, *srv);
995         l7vs_dest_c_str(dest_str, *dest);
996         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,111,
997             "in_function: static int l7vs_conn_is_rs_connected("
998             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
999             "iom=%s: "
1000             "conn=%s: "
1001             "srv=%s: "
1002             "dest=%s",
1003             iom_str, conn_str, srv_str, dest_str);
1004     }
1005     /*------ DEBUG LOG END ------*/
1006
1007     int ret = 0;
1008     struct l7vs_dest *d;    // destination for sorry-server
1009     int sorry_state;        // sorry state
1010
1011     struct l7vs_lsock *lsock = NULL;
1012
1013     if (!iom) {
1014         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,36, "error / iom is null");
1015         /*-------- DEBUG LOG --------*/
1016         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1017             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,112,
1018                 "out_function: static int l7vs_conn_is_rs_connected("
1019                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1020                 "return_value: 0");
1021         }
1022         /*------ DEBUG LOG END ------*/
1023         return 0;
1024     }
1025
1026     if (!conn) {
1027         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,37, "error / conn is null");
1028         /*-------- DEBUG LOG --------*/
1029         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1030             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,113,
1031                 "out_function: static int l7vs_conn_is_rs_connected("
1032                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1033                 "return_value: 0");
1034         }
1035         /*------ DEBUG LOG END ------*/
1036         return 0;
1037     }
1038
1039     if (iomux_conn_received != iom->status) {
1040         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,38, "error / invalid status(%d)", iom->status);
1041         /*-------- DEBUG LOG --------*/
1042         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1043             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,114,
1044                 "out_function: static int l7vs_conn_is_rs_connected("
1045                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1046                 "return_value: 0");
1047         }
1048         /*------ DEBUG LOG END ------*/
1049         return 0;
1050     }
1051
1052     lsock = conn->lsock;
1053     /*-------- DEBUG LOG --------*/
1054     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1055         char lsock_str[DEBUG_STR_LEN] = {0};
1056         l7vs_lsock_c_str(lsock_str, lsock);
1057         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,115,
1058             "pointer_assign: lsock=%s",
1059             lsock_str);
1060     }
1061     /*------ DEBUG LOG END ------*/
1062
1063     //is real server connected?
1064     if (-1 != conn->riom->fd) {
1065         // check sorry status of service
1066         // argment 0 means no connection count check
1067         sorry_state = l7vs_sched_sorry_check(conn->srv, 0);
1068         if (sorry_state) {
1069             // check connect to sorry-server now
1070             if (!conn->sorry_conn_flag) {
1071                 // get sorry-server destination (argment 0)
1072                 d = l7vs_sched_sorry_dest(conn->srv, conn, 0);
1073                 /*-------- DEBUG LOG --------*/
1074                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1075                     char sorry_dest_str1[DEBUG_STR_LEN] = {0};
1076                     l7vs_dest_c_str(sorry_dest_str1, d);
1077                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,116,
1078                         "pointer_assign: d=%s",
1079                         sorry_dest_str1);
1080                 }
1081                 /*------ DEBUG LOG END ------*/
1082                 if (!d) {
1083                     LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,18, "error / sorry-server dest NG");
1084                     /*-------- DEBUG LOG --------*/
1085                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1086                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,117,
1087                             "iom->status change: %d->%d",
1088                             iom->status, iomux_conn_rs_connect_error);
1089                     }
1090                     /*------ DEBUG LOG END ------*/
1091                     iom->status = iomux_conn_rs_connect_error;
1092                     /*-------- DEBUG LOG --------*/
1093                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1094                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,118,
1095                             "out_function: static int l7vs_conn_is_rs_connected("
1096                             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1097                             "return_value: 0");
1098                     }
1099                     /*------ DEBUG LOG END ------*/
1100                     return 0;
1101                 }
1102                 conn->old_dest = conn->dest;
1103                 /*-------- DEBUG LOG --------*/
1104                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1105                     char old_dest_str[DEBUG_STR_LEN] = {0};
1106                     l7vs_dest_c_str(old_dest_str, conn->old_dest);
1107                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,119,
1108                         "pointer_assign: conn->old_dest=%s",
1109                         old_dest_str);
1110                 }
1111                 /*------ DEBUG LOG END ------*/
1112                 // change connection to sorry-server
1113                 if (!l7vs_conn_change_connect_rs(conn, d)) {
1114                     LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,19, "error / change connection to Sorry NG");
1115                     /*-------- DEBUG LOG --------*/
1116                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1117                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,120,
1118                             "iom->status change: %d->%d",
1119                             iom->status, iomux_conn_rs_connect_error);
1120                     }
1121                     /*------ DEBUG LOG END ------*/
1122                     iom->status = iomux_conn_rs_connect_error;
1123                     /*-------- DEBUG LOG --------*/
1124                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1125                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,121,
1126                             "out_function: static int l7vs_conn_is_rs_connected("
1127                             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1128                             "return_value: 0");
1129                     }
1130                     /*------ DEBUG LOG END ------*/
1131                     return 0;
1132                 }
1133                 conn->sorry_conn_flag = 1;
1134             }
1135         } else {
1136             // check connect to sorry-server now
1137             if (conn->sorry_conn_flag) {
1138                 // get old real-server destination (argment 1)
1139                 d = l7vs_sched_sorry_dest(conn->srv, conn, 1);
1140                 /*-------- DEBUG LOG --------*/
1141                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1142                     char sorry_dest_str2[DEBUG_STR_LEN] = {0};
1143                     l7vs_dest_c_str(sorry_dest_str2, d);
1144                     LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,122,
1145                         "pointer_assign: d=%s",
1146                         sorry_dest_str2);
1147                 }
1148                 /*------ DEBUG LOG END ------*/
1149                 if (!d) {
1150                     LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,20, "error / old real-server dest NG");
1151                     /*-------- DEBUG LOG --------*/
1152                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1153                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,123,
1154                             "iom->status change: %d->%d",
1155                             iom->status, iomux_conn_rs_connect_error);
1156                     }
1157                     /*------ DEBUG LOG END ------*/
1158                     iom->status = iomux_conn_rs_connect_error;
1159                     /*-------- DEBUG LOG --------*/
1160                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1161                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,124,
1162                             "out_function: static int l7vs_conn_is_rs_connected("
1163                             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1164                             "return_value: 0");
1165                     }
1166                     /*------ DEBUG LOG END ------*/
1167                     return 0;
1168                 }
1169                 // change connection to real-server
1170                 if (!l7vs_conn_change_connect_rs(conn, d)) {
1171                     LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,21, "error / change connection to RS NG");
1172                     /*-------- DEBUG LOG --------*/
1173                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1174                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,125,
1175                             "iom->status change: %d->%d",
1176                             iom->status, iomux_conn_rs_connect_error);
1177                     }
1178                     /*------ DEBUG LOG END ------*/
1179                     iom->status = iomux_conn_rs_connect_error;
1180                     /*-------- DEBUG LOG --------*/
1181                     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1182                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,126,
1183                             "out_function: static int l7vs_conn_is_rs_connected("
1184                             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1185                             "return_value: 0");
1186                     }
1187                     /*------ DEBUG LOG END ------*/
1188                     return 0;
1189                 }
1190                 conn->sorry_conn_flag = 0;
1191             }
1192         }
1193         /*-------- DEBUG LOG --------*/
1194         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1195             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,127,
1196                 "iom->status change: %d->%d",
1197                 iom->status, iomux_conn_block);
1198         }
1199         /*------ DEBUG LOG END ------*/
1200         iom->status = iomux_conn_block;
1201         if (iomux_conn_busy == conn->riom->status) {
1202             /*-------- DEBUG LOG --------*/
1203             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1204                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,128,
1205                     "conn->riom->status change: %d->%d",
1206                     conn->riom->status, iomux_conn_sending_busy);
1207             }
1208             /*------ DEBUG LOG END ------*/
1209             conn->riom->status = iomux_conn_sending_busy;
1210         }
1211         else {
1212             /*-------- DEBUG LOG --------*/
1213             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1214                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,129,
1215                     "conn->riom->status change: %d->%d",
1216                     conn->riom->status, iomux_conn_sending);
1217             }
1218             /*------ DEBUG LOG END ------*/
1219             conn->riom->status = iomux_conn_sending;
1220         }
1221         //epoll re-registration for write
1222         l7vs_iomux_mod(conn->riom, iom_write);
1223     }
1224     else {
1225         //select service
1226         ret = l7vs_lsock_select_service(lsock, conn, conn->cldata,
1227                         conn->cldata_len, srv, dest);
1228         if (0 >= ret) {
1229             *srv = NULL;
1230             *dest = NULL;
1231             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,22, "error / no matching service found");
1232             /*-------- DEBUG LOG --------*/
1233             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1234                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,130,
1235                     "iom->status change: %d->%d",
1236                     iom->status, iomux_conn_receive_error);
1237             }
1238             /*------ DEBUG LOG END ------*/
1239             iom->status = iomux_conn_receive_error;
1240             /*-------- DEBUG LOG --------*/
1241             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1242                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,131,
1243                     "out_function: static int l7vs_conn_is_rs_connected("
1244                     "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1245                     "return_value: 0");
1246             }
1247             /*------ DEBUG LOG END ------*/
1248             return 0;
1249         }
1250         /*-------- DEBUG LOG --------*/
1251         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1252             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,132,
1253                 "iom->status change: %d->%d",
1254                 iom->status, iomux_conn_service_selected);
1255         }
1256         /*------ DEBUG LOG END ------*/
1257         iom->status = iomux_conn_service_selected;
1258     }
1259
1260     // analyze and modify client data
1261     if (conn->srv) {
1262         ret = conn->srv->pm->analyze_cldata(conn->srv, conn, conn->cldata, &conn->cldata_len);
1263         if (ret != 0) {
1264             // XXX
1265         }
1266     }
1267
1268     /*-------- DEBUG LOG --------*/
1269     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1270         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,133,
1271             "out_function: static int l7vs_conn_is_rs_connected("
1272             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service **srv, struct l7vs_dest **dest) "
1273             "return_value: 1");
1274     }
1275     /*------ DEBUG LOG END ------*/
1276     return 1;
1277 }
1278
1279 /*!
1280  * connecction establish
1281  *
1282  * @param[in]   iom     connection_iomux
1283  * @param[in]   conn    connection
1284  * @param[in]   srv     service
1285  * @param[in]   dest    destination(real server)
1286  * @return      status
1287  * @retval      0       failed
1288  * @retval      1       succeed
1289  */
1290 static int
1291 l7vs_conn_connection_establish(struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)
1292 {
1293     /*-------- DEBUG LOG --------*/
1294     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1295         char iom_str[DEBUG_STR_LEN] = {0};
1296         char conn_str[DEBUG_STR_LEN] = {0};
1297         char srv_str[DEBUG_STR_LEN] = {0};
1298         char dest_str[DEBUG_STR_LEN] = {0};
1299         l7vs_iomux_c_str(iom_str, iom);
1300         l7vs_conn_c_str(conn_str, conn);
1301         l7vs_service_c_str(srv_str, srv);
1302         l7vs_dest_c_str(dest_str, dest);
1303         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,134,
1304             "in_function: static int l7vs_conn_connection_establish("
1305             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1306             "iom=%s: "
1307             "conn=%s: "
1308             "srv=%s: "
1309             "dest=%s",
1310             iom_str, conn_str, srv_str, dest_str);
1311     }
1312     /*------ DEBUG LOG END ------*/
1313     int ret = 0;
1314
1315     if (!iom) {
1316         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,39, "error / iom is null");
1317         /*-------- DEBUG LOG --------*/
1318         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1319             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,135,
1320                 "out_function: static int l7vs_conn_connection_establish("
1321                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1322                 "return_value: 0");
1323         }
1324         /*------ DEBUG LOG END ------*/
1325         return 0;
1326     }
1327
1328     if (!conn) {
1329         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,40, "error / conn is null");
1330         /*-------- DEBUG LOG --------*/
1331         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1332             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,136,
1333                 "out_function: static int l7vs_conn_connection_establish("
1334                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1335                 "return_value: 0");
1336         }
1337         /*------ DEBUG LOG END ------*/
1338         return 0;
1339     }
1340
1341     if (!srv) {
1342         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,41, "error / srv is null");
1343         /*-------- DEBUG LOG --------*/
1344         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1345             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,137,
1346                 "out_function: static int l7vs_conn_connection_establish("
1347                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1348                 "return_value: 0");
1349         }
1350         /*------ DEBUG LOG END ------*/
1351         return 0;
1352     }
1353
1354     if (!dest) {
1355         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,42, "error / dest is null");
1356         /*-------- DEBUG LOG --------*/
1357         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1358             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,138,
1359                 "out_function: static int l7vs_conn_connection_establish("
1360                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1361                 "return_value: 0");
1362         }
1363         /*------ DEBUG LOG END ------*/
1364         return 0;
1365     }
1366
1367     if (iom->status != iomux_conn_service_selected) {
1368         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,43, "error / invalid status(%d)", iom->status);
1369         /*-------- DEBUG LOG --------*/
1370         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1371             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,139,
1372                 "out_function: static int l7vs_conn_connection_establish("
1373                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1374                 "return_value: 0");
1375         }
1376         /*------ DEBUG LOG END ------*/
1377         return 0;
1378     }
1379
1380     // connect to real server
1381     if (!l7vs_conn_connect_rs(conn, dest)) {
1382         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,23, "error / connect rs failed");
1383         /*-------- DEBUG LOG --------*/
1384         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1385             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,140,
1386                 "iom->status change: %d->%d",
1387                 iom->status, iomux_conn_rs_connect_error);
1388         }
1389         /*------ DEBUG LOG END ------*/
1390         iom->status = iomux_conn_rs_connect_error;
1391         /*-------- DEBUG LOG --------*/
1392         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1393             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,141,
1394                 "out_function: static int l7vs_conn_connection_establish("
1395                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1396                 "return_value: 0");
1397         }
1398         /*------ DEBUG LOG END ------*/
1399         return 0;
1400     }
1401     /*-------- DEBUG LOG --------*/
1402     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1403         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,142,
1404             "iom->status change: %d->%d",
1405             iom->status, iomux_conn_rs_connected);
1406     }
1407     /*------ DEBUG LOG END ------*/
1408     iom->status = iomux_conn_rs_connected;
1409
1410     // set pointer for cross reference
1411     conn->srv = srv;
1412     /*-------- DEBUG LOG --------*/
1413     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1414         char service_str[DEBUG_STR_LEN] = {0};
1415         l7vs_service_c_str(service_str, conn->srv);
1416         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,143,
1417             "pointer_assign: conn->srv=%s",
1418             service_str);
1419     }
1420     /*------ DEBUG LOG END ------*/
1421     l7vs_service_register_conn(srv, conn);
1422
1423     // service establish
1424     ret = l7vs_service_establish(conn->srv, conn);
1425     if (0 > ret) {
1426         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,24, "error / service establish failed");
1427         /*-------- DEBUG LOG --------*/
1428         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1429             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,144,
1430                 "iom->status change: %d->%d",
1431                 iom->status, iomux_conn_rs_connect_error);
1432         }
1433         /*------ DEBUG LOG END ------*/
1434         iom->status = iomux_conn_rs_connect_error;
1435         /*-------- DEBUG LOG --------*/
1436         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1437             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,145,
1438                 "out_function: static int l7vs_conn_connection_establish("
1439                 "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1440                 "return_value: 0");
1441         }
1442         /*------ DEBUG LOG END ------*/
1443         return 0;
1444     }
1445     
1446     // iom status set 
1447     /*-------- DEBUG LOG --------*/
1448     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1449         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,146,
1450             "iom->status change: %d->%d",
1451             iom->status, iomux_conn_block);
1452     }
1453     /*------ DEBUG LOG END ------*/
1454     iom->status = iomux_conn_block;
1455     /*-------- DEBUG LOG --------*/
1456     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1457         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,147,
1458             "conn->riom->status change: %d->%d",
1459             conn->riom->status, iomux_conn_sending);
1460     }
1461     /*------ DEBUG LOG END ------*/
1462     conn->riom->status = iomux_conn_sending;
1463
1464     /*-------- DEBUG LOG --------*/
1465     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1466         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,148,
1467             "out_function: static int l7vs_conn_connection_establish("
1468             "struct l7vs_iomux *iom, struct l7vs_conn *conn, struct l7vs_service *srv, struct l7vs_dest *dest)"
1469             "return_value: 1");
1470     }
1471     /*------ DEBUG LOG END ------*/
1472     return 1;
1473 }
1474
1475 /*!
1476  * block status:
1477  * when block status, arrived data turn next epoll reaction
1478  * and changes state to busy, expect the another iom is already busy
1479  *
1480  * @param[in]   iom         connection_iomux
1481  * @param[in]   another_iom another side's iomux
1482  * @return      status
1483  * @retval      0       failed
1484  * @retval      1       succeed
1485  */
1486 static int
1487 l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom)
1488 {
1489     /*-------- DEBUG LOG --------*/
1490     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1491         char iom_str[DEBUG_STR_LEN] = {0};
1492         char a_iom_str[DEBUG_STR_LEN] = {0};
1493         l7vs_iomux_c_str(iom_str, iom);
1494         l7vs_iomux_c_str(a_iom_str, another_iom);
1495         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,149,
1496             "in_function: static int l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1497             "iom=%s: "
1498             "another_iom=%s",
1499             iom_str, a_iom_str);
1500     }
1501     /*------ DEBUG LOG END ------*/
1502
1503     if (!iom) {
1504         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,44, "error / iom is null");
1505         /*-------- DEBUG LOG --------*/
1506         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1507             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,150,
1508                 "out_function: static int l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1509                 "return_value: 0");
1510         }
1511         /*------ DEBUG LOG END ------*/
1512         return 0;
1513     }
1514
1515     if (!another_iom) {
1516         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,45, "error / another_iom is null");
1517         /*-------- DEBUG LOG --------*/
1518         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1519             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,151,
1520                 "out_function: static int l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1521                 "return_value: 0");
1522         }
1523         /*------ DEBUG LOG END ------*/
1524         return 0;
1525     }
1526
1527     if (iomux_conn_block != iom->status) {
1528         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,46, "error / invalid status(%d)", iom->status);
1529         /*-------- DEBUG LOG --------*/
1530         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1531             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,152,
1532                 "out_function: static int l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1533                 "return_value: 0");
1534         }
1535         /*------ DEBUG LOG END ------*/
1536         return 0;
1537     }
1538
1539     // epoll re-registraion for read
1540     l7vs_iomux_mod(iom, iom_read);
1541
1542     // when another iom status is busy, do not change my status
1543     if (iomux_conn_busy != another_iom->status &&
1544         iomux_conn_sending_busy != another_iom->status &&
1545         iomux_conn_sent_busy != another_iom->status) {
1546         /*-------- DEBUG LOG --------*/
1547         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1548             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,153,
1549                 "iom->status change: %d->%d",
1550                 iom->status, iomux_conn_busy);
1551         }
1552         /*------ DEBUG LOG END ------*/
1553         iom->status = iomux_conn_busy;
1554     }
1555
1556     /*-------- DEBUG LOG --------*/
1557     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1558         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,154,
1559             "out_function: static int l7vs_conn_block(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1560             "return_value: 1");
1561     }
1562     /*------ DEBUG LOG END ------*/
1563     return 1;
1564 }
1565
1566 /*!
1567  * busy status:
1568  * when busy status, arrived data turn next epoll reaction and status keep busy
1569  *
1570  * @param[in]   iom     connection_iomux
1571  * @return      status
1572  * @retval      0       failed
1573  * @retval      1       succeed
1574  */
1575 static int
1576 l7vs_conn_busy(struct l7vs_iomux *iom)
1577 {
1578     /*-------- DEBUG LOG --------*/
1579     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1580         char iom_str[DEBUG_STR_LEN] = {0};
1581         l7vs_iomux_c_str(iom_str, iom);
1582         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,155,
1583             "in_function: static int l7vs_conn_busy(struct l7vs_iomux *iom) "
1584             "iom=%s",
1585             iom_str);
1586     }
1587     /*------ DEBUG LOG END ------*/
1588
1589     if (!iom) {
1590         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,47, "error / iom is null");
1591         /*-------- DEBUG LOG --------*/
1592         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1593             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,156,
1594                 "out_function: static int l7vs_conn_busy(struct l7vs_iomux *iom) "
1595                 "return_value: 0");
1596         }
1597         /*------ DEBUG LOG END ------*/
1598         return 0;
1599     }
1600
1601     if (iomux_conn_busy != iom->status) {
1602         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,48, "error / invalid status(%d)", iom->status);
1603         /*-------- DEBUG LOG --------*/
1604         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1605             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,157,
1606                 "out_function: static int l7vs_conn_busy(struct l7vs_iomux *iom) "
1607                 "return_value: 0");
1608         }
1609         /*------ DEBUG LOG END ------*/
1610         return 0;
1611     }
1612
1613     //epoll re-registration for read
1614     // l7vs_iomux_mod(iom, iom_read);
1615
1616     /*-------- DEBUG LOG --------*/
1617     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1618         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,158,
1619             "out_function: static int l7vs_conn_busy(struct l7vs_iomux *iom) "
1620             "return_value: 1");
1621     }
1622     /*------ DEBUG LOG END ------*/
1623     return 1;
1624 }
1625
1626 /*!
1627  * sending status:
1628  * 
1629  * @param[in]   iom         connection_iomux
1630  * @param[in]   another_iom another side's iomux
1631  * @return      status
1632  * @retval      0       failed
1633  * @retval      1       succeed
1634  */
1635 static int
1636 l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom)
1637 {
1638     /*-------- DEBUG LOG --------*/
1639     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1640         char iom_str[DEBUG_STR_LEN] = {0};
1641         char a_iom_str[DEBUG_STR_LEN] = {0};
1642         l7vs_iomux_c_str(iom_str, iom);
1643         l7vs_iomux_c_str(a_iom_str, another_iom);
1644         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,159,
1645             "in_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1646             "iom=%s: "
1647             "another_iom=%s",
1648             iom_str, a_iom_str);
1649     }
1650     /*------ DEBUG LOG END ------*/
1651
1652     if (!iom) {
1653         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,49, "error / iom is null");
1654         /*-------- DEBUG LOG --------*/
1655         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1656             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,160,
1657                 "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1658                 "return_value: 0");
1659         }
1660         /*------ DEBUG LOG END ------*/
1661         return 0; 
1662     }
1663
1664     if (!another_iom) {
1665         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,50, "error / another_iom is null");
1666         /*-------- DEBUG LOG --------*/
1667         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1668             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,161,
1669                 "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1670                 "return_value: 0");
1671         }
1672         /*------ DEBUG LOG END ------*/
1673         return 0; 
1674     }
1675
1676     if (iomux_conn_sending != iom->status && iomux_conn_sending_busy != iom->status) {
1677         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,51, "error / invalid status(%d)", iom->status);
1678         /*-------- DEBUG LOG --------*/
1679         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1680             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,162,
1681                 "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1682                 "return_value: 0");
1683         }
1684         /*------ DEBUG LOG END ------*/
1685         return 0;
1686     }
1687
1688     // send to handling iom
1689     if (!l7vs_conn_send(iom, iom->fd)) {
1690         iom->status = iomux_conn_send_error;
1691         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,25, "error / send failed");
1692         /*-------- DEBUG LOG --------*/
1693         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1694             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,163,
1695                 "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1696                 "return_value: 0");
1697         }
1698         /*------ DEBUG LOG END ------*/
1699         return 0;
1700     }
1701     if (iomux_conn_sent == iom->status || iomux_conn_sent_busy == iom->status) {
1702         // when all data was sent, select the next state
1703         if (!l7vs_conn_sent_next_state(another_iom, iom)) {
1704             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,26, "error / send next state failed");
1705             /*-------- DEBUG LOG --------*/
1706             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1707                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,164,
1708                     "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1709                     "return_value: 0");
1710             }
1711             /*------ DEBUG LOG END ------*/
1712             return 0;
1713         }
1714         if (iomux_conn_receiving != iom->status && iomux_conn_block != iom->status) {
1715             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,52, "error / invalid status(%d)", iom->status);
1716             /*-------- DEBUG LOG --------*/
1717             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1718                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,165,
1719                     "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1720                     "return_value: 0");
1721             }
1722             /*------ DEBUG LOG END ------*/
1723             return 0;
1724         }
1725     }
1726     else if (iomux_conn_sending == iom->status || iomux_conn_sending_busy == iom->status) {
1727         // data still remain
1728         // epoll re-registration for write
1729         l7vs_iomux_mod(iom, iom_write);
1730     }
1731     else  {
1732         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,53, "error / invalid status(%d)", iom->status);
1733         /*-------- DEBUG LOG --------*/
1734         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1735             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,166,
1736                 "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1737                 "return_value: 0");
1738         }
1739         /*------ DEBUG LOG END ------*/
1740         return 0;
1741     }
1742
1743     /*-------- DEBUG LOG --------*/
1744     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1745         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,167,
1746             "out_function: static int l7vs_conn_sending(struct l7vs_iomux *iom, struct l7vs_iomux *another_iom) "
1747             "return_value: 1");
1748     }
1749     /*------ DEBUG LOG END ------*/
1750     return 1;
1751 }
1752
1753 /*!
1754  * decide sent next state
1755  *
1756  * @param[in,out]   src_iom     source connection_iomux
1757  * @param[in,out]   dest_iom    destionation connection_iomux
1758  * @return      status
1759  * @retval      0       failed
1760  * @retval      1       succeed
1761  */
1762 static int
1763 l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom)
1764 {
1765     /*-------- DEBUG LOG --------*/
1766     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1767         char s_iom_str[DEBUG_STR_LEN] = {0};
1768         char d_iom_str[DEBUG_STR_LEN] = {0};
1769         l7vs_iomux_c_str(s_iom_str, src_iom);
1770         l7vs_iomux_c_str(d_iom_str, dest_iom);
1771         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,168,
1772             "in_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1773             "src_iom=%s: "
1774             "dest_iom=%s",
1775             s_iom_str, d_iom_str);
1776     }
1777     /*------ DEBUG LOG END ------*/
1778
1779     if (!src_iom) {
1780         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,54, "error / src_iom is null");
1781         /*-------- DEBUG LOG --------*/
1782         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1783             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,169,
1784                 "out_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1785                 "return_value: 0");
1786         }
1787         /*------ DEBUG LOG END ------*/
1788         return  0;
1789     }
1790     if (!dest_iom) {
1791         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,55, "error / dest_iom is null");
1792         /*-------- DEBUG LOG --------*/
1793         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1794             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,170,
1795                 "out_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1796                 "return_value: 0");
1797         }
1798         /*------ DEBUG LOG END ------*/
1799         return  0;
1800     }
1801
1802     // when writing, the dest_status will be "sent" or "sent_busy"
1803     if (iomux_conn_sent != dest_iom->status && iomux_conn_sent_busy != dest_iom->status) {
1804         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,56, "error / invalid dest status(%d)", dest_iom->status);
1805         /*-------- DEBUG LOG --------*/
1806         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1807             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,171,
1808                 "out_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1809                 "return_value: 0");
1810         }
1811         /*------ DEBUG LOG END ------*/
1812         return 0;
1813     }
1814     // and the src_status will be "block" or "busy"
1815     if (iomux_conn_block != src_iom->status && iomux_conn_busy != src_iom->status) {
1816         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,57, "error / invalid src status(%d)", src_iom->status);
1817         /*-------- DEBUG LOG --------*/
1818         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1819             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,172,
1820                 "out_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1821                 "return_value: 0");
1822         }
1823         /*------ DEBUG LOG END ------*/
1824         return 0;
1825     }
1826
1827     // decide the next state
1828     if (iomux_conn_sent_busy == dest_iom->status) {
1829         // when receiving from source, request come to the destination, then destination has priority
1830         /*-------- DEBUG LOG --------*/
1831         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1832             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,173,
1833                 "src_iom->status change: %d->%d",
1834                 src_iom->status, iomux_conn_block);
1835         }
1836         /*------ DEBUG LOG END ------*/
1837         src_iom->status = iomux_conn_block;
1838         /*-------- DEBUG LOG --------*/
1839         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1840             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,174,
1841                 "dest_iom->status change: %d->%d",
1842                 dest_iom->status, iomux_conn_receiving);
1843         }
1844         /*------ DEBUG LOG END ------*/
1845         dest_iom->status = iomux_conn_receiving;
1846     }
1847     else if (iomux_conn_busy == src_iom->status) {
1848         // when sending to destination, request come to the source, then source has priority
1849         /*-------- DEBUG LOG --------*/
1850         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1851             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,175,
1852                 "src_iom->status change: %d->%d",
1853                 src_iom->status, iomux_conn_receiving);
1854         }
1855         /*------ DEBUG LOG END ------*/
1856         src_iom->status = iomux_conn_receiving;
1857         /*-------- DEBUG LOG --------*/
1858         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1859             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,176,
1860                 "dest_iom->status change: %d->%d",
1861                 dest_iom->status, iomux_conn_block);
1862         }
1863         /*------ DEBUG LOG END ------*/
1864         dest_iom->status = iomux_conn_block;
1865     }
1866     else {
1867         // request come to neither source nor destnation, ready to read both
1868         /*-------- DEBUG LOG --------*/
1869         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1870             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,177,
1871                 "src_iom->status change: %d->%d",
1872                 src_iom->status, iomux_conn_receiving);
1873         }
1874         /*------ DEBUG LOG END ------*/
1875         src_iom->status = iomux_conn_receiving;
1876         /*-------- DEBUG LOG --------*/
1877         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1878             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,178,
1879                 "dest_iom->status change: %d->%d",
1880                 dest_iom->status, iomux_conn_receiving);
1881         }
1882         /*------ DEBUG LOG END ------*/
1883         dest_iom->status = iomux_conn_receiving;
1884     }
1885     l7vs_iomux_mod(src_iom, iom_read);
1886     l7vs_iomux_mod(dest_iom, iom_read);
1887
1888     /*-------- DEBUG LOG --------*/
1889     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1890         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,179,
1891             "out_function: static int l7vs_conn_sent_next_state(struct l7vs_iomux *src_iom, struct l7vs_iomux *dest_iom) "
1892             "return_value: 1");
1893     }
1894     /*------ DEBUG LOG END ------*/
1895     return 1;
1896 }
1897
1898 /*!
1899  * realserver connection callback
1900  *
1901  * @param[in]   iom     connection iomux
1902  * @return      status
1903  * @retval      0       failed
1904  * @retval      1       succeed
1905  */
1906 static int
1907 l7vs_conn_rs_callback(struct l7vs_iomux *iom)
1908 {
1909     /*-------- DEBUG LOG --------*/
1910     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1911         char iom_str[DEBUG_STR_LEN] = {0};
1912         l7vs_iomux_c_str(iom_str, iom);
1913         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,180,
1914             "in_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
1915             "iom=%s",
1916             iom_str);
1917     }
1918     /*------ DEBUG LOG END ------*/
1919     struct l7vs_conn* conn = NULL;
1920
1921     if (!iom) {
1922         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,58, "error / iom is null");
1923         /*-------- DEBUG LOG --------*/
1924         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1925             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,181,
1926                 "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
1927                 "return_value: 0");
1928         }
1929         /*------ DEBUG LOG END ------*/
1930         return 0;
1931     }
1932
1933     conn = (struct l7vs_conn *)iom->data;
1934     /*-------- DEBUG LOG --------*/
1935     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1936         char conn_str[DEBUG_STR_LEN] = {0};
1937         l7vs_conn_c_str(conn_str, conn);
1938         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,182,
1939             "pointer_assign: conn=%s",
1940             conn_str);
1941     }
1942     /*------ DEBUG LOG END ------*/
1943
1944     // invalid status check
1945     if (iomux_conn_receiving != iom->status &&
1946         iomux_conn_block != iom->status &&
1947         iomux_conn_busy != iom->status && 
1948         iomux_conn_sending != iom->status && 
1949         iomux_conn_sending_busy != iom->status) {
1950         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,59, "error / invalid status(%d)", iom->status);
1951         l7vs_conn_destroy(conn);
1952         /*-------- DEBUG LOG --------*/
1953         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1954             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,183,
1955                 "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
1956                 "return_value: 0");
1957         }
1958         /*------ DEBUG LOG END ------*/
1959         return 0;
1960     }
1961
1962     // switch by current status
1963     switch (iom->status) {
1964     case iomux_conn_receiving:
1965         if (!l7vs_conn_realserver_receiving(iom)) {
1966             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,27, "error / rs_callback/realserver receiving failed");
1967             l7vs_conn_destroy(conn);
1968             /*-------- DEBUG LOG --------*/
1969             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1970                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,184,
1971                     "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
1972                     "return_value: 0");
1973             }
1974             /*------ DEBUG LOG END ------*/
1975             return 0;
1976         }
1977         if (iomux_conn_disconnected == iom->status) {
1978             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1979                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,185, "realserver connection disconnected");
1980             }
1981             l7vs_conn_destroy(conn);
1982         }
1983         break;
1984     case iomux_conn_block:
1985         if (!l7vs_conn_block(iom, conn->ciom)) {
1986             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,28, "error / rs_callback/block failed");
1987             l7vs_conn_destroy(conn);
1988             /*-------- DEBUG LOG --------*/
1989             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
1990                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,186,
1991                     "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
1992                     "return_value: 0");
1993             }
1994             /*------ DEBUG LOG END ------*/
1995             return 0;
1996         }
1997         break;
1998     case iomux_conn_busy:
1999         if (!l7vs_conn_busy(iom)) {
2000             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,29, "error / rs_callback/busy failed");
2001             l7vs_conn_destroy(conn);
2002             /*-------- DEBUG LOG --------*/
2003             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2004                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,187,
2005                     "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
2006                     "return_value: 0");
2007             }
2008             /*------ DEBUG LOG END ------*/
2009             return 0;
2010         }
2011         break;
2012     case iomux_conn_sending:
2013         if (!l7vs_conn_sending(iom, conn->ciom)) {
2014             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,30, "error / rs_callback/sending failed");
2015             l7vs_conn_destroy(conn);
2016             /*-------- DEBUG LOG --------*/
2017             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2018                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,188,
2019                     "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
2020                     "return_value: 0");
2021             }
2022             /*------ DEBUG LOG END ------*/
2023             return 0;
2024         }
2025         break;
2026     case iomux_conn_sending_busy:
2027         if (!l7vs_conn_sending(iom, conn->ciom)) {
2028             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,31, "error / rs_callback/sending_busy failed");
2029             l7vs_conn_destroy(conn);
2030             /*-------- DEBUG LOG --------*/
2031             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2032                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,189,
2033                     "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
2034                     "return_value: 0");
2035             }
2036             /*------ DEBUG LOG END ------*/
2037             return 0;
2038         }
2039         break;
2040     default:
2041         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,60, "error / invalid status(%d)", iom->status);
2042         l7vs_conn_destroy(conn);
2043         /*-------- DEBUG LOG --------*/
2044         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2045             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,190,
2046                 "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
2047                 "return_value: 0");
2048         }
2049         /*------ DEBUG LOG END ------*/
2050         return 0;
2051     }
2052
2053     /*-------- DEBUG LOG --------*/
2054     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2055         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,191,
2056             "out_function: static int l7vs_conn_rs_callback(struct l7vs_iomux *iom) "
2057             "return_value: 1");
2058     }
2059     /*------ DEBUG LOG END ------*/
2060     return 1;
2061 }
2062
2063 /*!
2064  * realserver receiving 
2065  *
2066  * @param[in]   iom     connection iomux
2067  * @return      status
2068  * @retval      0       failed
2069  * @retval      1       succeed
2070  */
2071 static int
2072 l7vs_conn_realserver_receiving(struct l7vs_iomux *iom)
2073 {
2074     /*-------- DEBUG LOG --------*/
2075     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2076         char iom_str[DEBUG_STR_LEN] = {0};
2077         l7vs_iomux_c_str(iom_str, iom);
2078         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,192,
2079             "in_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2080             "iom=%s",
2081             iom_str);
2082     }
2083     /*------ DEBUG LOG END ------*/
2084
2085     struct l7vs_conn *conn = NULL;
2086
2087     if (!iom) {
2088         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,61, "error / iom is null");
2089         /*-------- DEBUG LOG --------*/
2090         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2091             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,193,
2092                 "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2093                 "return_value: 0");
2094         }
2095         /*------ DEBUG LOG END ------*/
2096         return 0;
2097     }
2098
2099     if (iomux_conn_receiving != iom->status) {
2100         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,62, "error / invalid status(%d)", iom->status);
2101         /*-------- DEBUG LOG --------*/
2102         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2103             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,194,
2104                 "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2105                 "return_value: 0");
2106         }
2107         /*------ DEBUG LOG END ------*/
2108         return 0;
2109     }
2110
2111     conn = (struct l7vs_conn *)iom->data;
2112     /*-------- DEBUG LOG --------*/
2113     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2114         char conn_str[DEBUG_STR_LEN] = {0};
2115         l7vs_conn_c_str(conn_str, conn);
2116         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,195,
2117             "pointer_assign: conn=%s",
2118             conn_str);
2119     }
2120     /*------ DEBUG LOG END ------*/
2121
2122     // when the client is not set in read-blocked
2123     if (iomux_conn_block != conn->ciom->status && iomux_conn_busy != conn->ciom->status) {
2124         // set the real server in read-blocked
2125         /*-------- DEBUG LOG --------*/
2126         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2127             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,196,
2128                 "conn->ciom->status change: %d->%d",
2129                 conn->ciom->status, iomux_conn_block);
2130         }
2131         /*------ DEBUG LOG END ------*/
2132         conn->ciom->status = iomux_conn_block;
2133     }
2134
2135     // receive realserver data
2136     if (!l7vs_conn_recv(iom, iom->fd)) {
2137         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,32, "error / recv failed");
2138         /*-------- DEBUG LOG --------*/
2139         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2140             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,197,
2141                 "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2142                 "return_value: 0");
2143         }
2144         /*------ DEBUG LOG END ------*/
2145         return 0;
2146     }
2147     switch (iom->status) {
2148     case iomux_conn_receiving:
2149         // data still remain, epoll re-registration for read
2150         l7vs_iomux_mod(iom, iom_read);
2151         break;
2152     case iomux_conn_received:
2153         // all data is received, append the session infomation
2154         if (!l7vs_conn_realserver_modify_data(iom)) {
2155             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,33, "error / realserver modify data failed");
2156             /*-------- DEBUG LOG --------*/
2157             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2158                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,198,
2159                     "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2160                     "return_value: 0");
2161             }
2162             /*------ DEBUG LOG END ------*/
2163             return 0;
2164         }
2165         /*-------- DEBUG LOG --------*/
2166         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2167             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,199,
2168                 "iom->status change: %d->%d",
2169                 iom->status, iomux_conn_block);
2170         }
2171         /*------ DEBUG LOG END ------*/
2172         iom->status = iomux_conn_block;
2173         if (iomux_conn_busy == conn->ciom->status) {
2174             /*-------- DEBUG LOG --------*/
2175             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2176                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,200,
2177                     "conn->ciom->status change: %d->%d",
2178                     conn->ciom->status, iomux_conn_sending_busy);
2179             }
2180             /*------ DEBUG LOG END ------*/
2181             conn->ciom->status = iomux_conn_sending_busy;
2182         } else {
2183             /*-------- DEBUG LOG --------*/
2184             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2185                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,201,
2186                     "conn->ciom->status change: %d->%d",
2187                     conn->ciom->status, iomux_conn_sending);
2188             }
2189             /*------ DEBUG LOG END ------*/
2190             conn->ciom->status = iomux_conn_sending;
2191         }
2192         //epoll re-registration for write
2193         l7vs_iomux_mod(conn->ciom, iom_write);
2194     case iomux_conn_disconnected:
2195         // client connection was disconnected
2196         break;
2197     default:
2198         //invalid status
2199         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,63, "error / invalid status(%d)", iom->status);
2200         /*-------- DEBUG LOG --------*/
2201         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2202             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,202,
2203                 "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2204                 "return_value: 0");
2205         }
2206         /*------ DEBUG LOG END ------*/
2207         return 0;
2208     }
2209
2210     /*-------- DEBUG LOG --------*/
2211     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2212         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,203,
2213             "out_function: static int l7vs_conn_realserver_receiving(struct l7vs_iomux *iom) "
2214             "return_value: 1");
2215     }
2216     /*------ DEBUG LOG END ------*/
2217     return 1;
2218 }
2219
2220 /*!
2221  * realserver modify data
2222  *
2223  * @param[in]   iom     connection iomux
2224  * @return      status
2225  * @retval      0       failed
2226  * @retval      1       succeed
2227  */
2228 static int
2229 l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom)
2230 {
2231     /*-------- DEBUG LOG --------*/
2232     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2233         char iom_str[DEBUG_STR_LEN] = {0};
2234         l7vs_iomux_c_str(iom_str, iom);
2235         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,204,
2236             "in_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2237             "iom=%s",
2238             iom_str);
2239     }
2240     /*------ DEBUG LOG END ------*/
2241     struct l7vs_conn *conn = NULL;
2242         char *newbuf = NULL;
2243     int (*relayf)(struct l7vs_service *, struct l7vs_conn *, char *, size_t *) = NULL;
2244     int ret = 0;
2245     size_t len_ret = 0;
2246
2247     if (!iom) {
2248         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,64, "error / iom is null");
2249         /*-------- DEBUG LOG --------*/
2250         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2251             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,205,
2252                 "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2253                 "return_value: 0");
2254         }
2255         /*------ DEBUG LOG END ------*/
2256         return 0;
2257     }
2258
2259     if (iomux_conn_received != iom->status) {
2260         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,65, "error / invalid status(%d)", iom->status);
2261         /*-------- DEBUG LOG --------*/
2262         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2263             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,206,
2264                 "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2265                 "return_value: 0");
2266         }
2267         /*------ DEBUG LOG END ------*/
2268         return 0;
2269     }
2270
2271     conn = (struct l7vs_conn *)iom->data;
2272     /*-------- DEBUG LOG --------*/
2273     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2274         char conn_str[DEBUG_STR_LEN] = {0};
2275         l7vs_conn_c_str(conn_str, conn);
2276         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,207,
2277             "pointer_assign: conn=%s",
2278             conn_str);
2279     }
2280     /*------ DEBUG LOG END ------*/
2281
2282     //set the function pointer that modify the real server data
2283     if (conn->srv) {
2284         relayf = conn->srv->pm->analyze_rsdata;
2285         /*-------- DEBUG LOG --------*/
2286         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2287             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,208,
2288                 "pointer_assign: relayf=%p",
2289                 relayf);
2290         }
2291         /*------ DEBUG LOG END ------*/
2292     }
2293
2294     if (relayf) {
2295         len_ret = conn->cldata_len;
2296         newbuf = (char *)realloc(conn->cldata, (conn->cldata_len + L7VS_PROTOMOD_MAX_ADD_BUFSIZE + 1));
2297         if (!newbuf) {
2298             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,10, "error / realloc failed");
2299             iom->status = iomux_conn_buffer_realloc_error;
2300             /*-------- DEBUG LOG --------*/
2301             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2302                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,209,
2303                     "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2304                     "return_value: 0");
2305             }
2306             /*------ DEBUG LOG END ------*/
2307             return 0;
2308         }
2309         /*-------- DEBUG LOG --------*/
2310         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2311             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,210,
2312                 "realloc: newbuf=%p: size=%zu",
2313                 newbuf, (conn->cldata_len + L7VS_PROTOMOD_MAX_ADD_BUFSIZE + 1));
2314         }
2315         /*------ DEBUG LOG END ------*/
2316         conn->cldata = newbuf;
2317
2318         ret = (*relayf)(conn->srv, conn, conn->cldata, &len_ret);
2319         if (0 != ret) {
2320             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,34, "error / analyze rsdata failed");
2321             /*-------- DEBUG LOG --------*/
2322             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2323                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,211,
2324                     "iom->status change: %d->%d",
2325                     iom->status, iomux_conn_rsdata_modify_error);
2326             }
2327             /*------ DEBUG LOG END ------*/
2328             iom->status = iomux_conn_rsdata_modify_error;
2329             /*-------- DEBUG LOG --------*/
2330             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2331                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,212,
2332                     "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2333                     "return_value: 0");
2334             }
2335             /*------ DEBUG LOG END ------*/
2336             return 0;
2337         }
2338         if (L7VS_PROTOMOD_MAX_ADD_BUFSIZE < len_ret - conn->cldata_len) {
2339             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,35, "error / bufsize too long modified by protomod");
2340             /*-------- DEBUG LOG --------*/
2341             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2342                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,213,
2343                     "iom->status change: %d->%d",
2344                     iom->status, iomux_conn_rsdata_modify_error);
2345             }
2346             /*------ DEBUG LOG END ------*/
2347             iom->status = iomux_conn_rsdata_modify_error;
2348             /*-------- DEBUG LOG --------*/
2349             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2350                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,214,
2351                     "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2352                     "return_value: 0");
2353             }
2354             /*------ DEBUG LOG END ------*/
2355             return 0;
2356         }
2357         else {
2358             conn->cldata_len = len_ret;
2359         }
2360     }
2361     /*-------- DEBUG LOG --------*/
2362     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2363         char modify_data[DEBUG_STR_LEN] = {0};
2364         l7vs_conn_dump_data(modify_data, conn->cldata, conn->cldata_len);
2365         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,215,
2366             "modify data: %s",
2367             modify_data);
2368     }
2369     /*------ DEBUG LOG END ------*/
2370
2371     /*-------- DEBUG LOG --------*/
2372     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2373         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,216,
2374             "iom->status change: %d->%d",
2375             iom->status, iomux_conn_rsdata_modified);
2376     }
2377     /*------ DEBUG LOG END ------*/
2378     iom->status = iomux_conn_rsdata_modified;
2379     /*-------- DEBUG LOG --------*/
2380     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2381         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,217,
2382             "out_function: static int l7vs_conn_realserver_modify_data(struct l7vs_iomux *iom) "
2383             "return_value: 1");
2384     }
2385     /*------ DEBUG LOG END ------*/
2386     return 1;
2387 }
2388
2389 /*!
2390  * receive data
2391  *
2392  * @param[in]   iom         connection_iomux
2393  * @param[in]   source_fd   the filedescriptor to be read
2394  * @return      status
2395  * @retval      0       failed 
2396  * @retval      1       succeed
2397  */
2398 static int
2399 l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd)
2400 {
2401     /*-------- DEBUG LOG --------*/
2402     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2403         char iom_str[DEBUG_STR_LEN] = {0};
2404         l7vs_iomux_c_str(iom_str, iom);
2405         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,218,
2406             "in_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2407             "iom=%s: "
2408             "source_fd=%d",
2409             iom_str, source_fd);
2410     }
2411     /*------ DEBUG LOG END ------*/
2412         int ret = 0;
2413     struct l7vs_conn *conn = NULL;
2414     char read_buf[l7vs_conn_read_bufsize];
2415 //        char *newbuf = NULL;
2416
2417     if (!iom) {
2418         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,66, "error / iom is null");
2419         /*-------- DEBUG LOG --------*/
2420         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2421             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,219,
2422                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2423                 "return_value: 0");
2424         }
2425         /*------ DEBUG LOG END ------*/
2426         return 0;
2427     }
2428
2429     if (0 > source_fd || INT_MAX == source_fd) {
2430         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,67, "error / source fd is not specified");
2431         /*-------- DEBUG LOG --------*/
2432         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2433             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,220,
2434                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2435                 "return_value: 0");
2436         }
2437         /*------ DEBUG LOG END ------*/
2438         return 0;
2439     }
2440
2441     if (iomux_conn_receiving != iom->status) {
2442         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,68, "error / invalid status(%d)", iom->status);
2443         /*-------- DEBUG LOG --------*/
2444         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2445             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,221,
2446                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2447                 "return_value: 0");
2448         }
2449         /*------ DEBUG LOG END ------*/
2450         return 0;
2451     }
2452
2453     conn = (struct l7vs_conn *)iom->data;
2454     /*-------- DEBUG LOG --------*/
2455     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2456         char conn_str[DEBUG_STR_LEN] = {0};
2457         l7vs_conn_c_str(conn_str, conn);
2458         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,222,
2459             "pointer_assign: conn=%s",
2460             conn_str);
2461     }
2462     /*------ DEBUG LOG END ------*/
2463
2464     //QoS Control to server
2465     if( (source_fd == conn->ciom->fd) && !l7vs_conn_QoS_control( conn, QOS_UP ) ){
2466         /*-------- DEBUG LOG --------*/
2467         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2468             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,223,
2469                 "iom->status change: %d->%d",
2470                 iom->status, iomux_conn_receiving);
2471         }
2472         /*------ DEBUG LOG END ------*/
2473         iom->status = iomux_conn_receiving;
2474         /*-------- DEBUG LOG --------*/
2475         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2476             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,224,
2477                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2478                 "return_value: 1");
2479         }
2480         /*------ DEBUG LOG END ------*/
2481         return 1;
2482     }
2483     //QoS Control to client
2484     if( (source_fd == conn->riom->fd) && !l7vs_conn_QoS_control( conn, QOS_DOWN ) ){
2485         /*-------- DEBUG LOG --------*/
2486         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2487             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,223,
2488                 "iom->status change: %d->%d",
2489                 iom->status, iomux_conn_receiving);
2490         }
2491         /*------ DEBUG LOG END ------*/
2492         iom->status = iomux_conn_receiving;
2493         /*-------- DEBUG LOG --------*/
2494         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2495             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,224,
2496                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2497                 "return_value: 1");
2498         }
2499         /*------ DEBUG LOG END ------*/
2500         return 1;
2501     }
2502     // read the data
2503     /*-------- DEBUG LOG --------*/
2504     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2505         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,225,
2506             "recv param: source_fd=%d: len=%d: flags=%d",
2507             source_fd, (l7vs_conn_read_bufsize - 1), 0);
2508     }
2509     /*------ DEBUG LOG END ------*/
2510     ret = recv(source_fd, read_buf, (l7vs_conn_read_bufsize - 1), 0);
2511     /*-------- DEBUG LOG --------*/
2512     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2513         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,226,
2514             "recv result: ret=%d",
2515             ret);
2516     }
2517     /*------ DEBUG LOG END ------*/
2518     /*-------- DEBUG LOG --------*/
2519     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2520         char recv_data[DEBUG_STR_LEN] = {0};
2521         l7vs_conn_dump_data(recv_data, read_buf, ret);
2522         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,227,
2523             "recv data: %s",
2524             recv_data);
2525     }
2526     /*------ DEBUG LOG END ------*/
2527     switch (ret) {
2528     case -1:
2529         if (EAGAIN != errno) {
2530             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,12, "error / recv error(%s)", strerror(errno));
2531             /*-------- DEBUG LOG --------*/
2532             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2533                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,228,
2534                     "iom->status change: %d->%d",
2535                     iom->status, iomux_conn_receive_error);
2536             }
2537             /*------ DEBUG LOG END ------*/
2538             iom->status = iomux_conn_receive_error;
2539             /*-------- DEBUG LOG --------*/
2540             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2541                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,229,
2542                     "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2543                     "return_value: 0");
2544             }
2545             /*------ DEBUG LOG END ------*/
2546             return 0;
2547         }
2548         /*-------- DEBUG LOG --------*/
2549         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2550             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,230,
2551                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2552                 "return_value: 1");
2553         }
2554         /*------ DEBUG LOG END ------*/
2555         return 1;
2556     case 0:
2557         /*-------- DEBUG LOG --------*/
2558         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2559             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,231, "peer disconnected");
2560             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,232,
2561                 "iom->status change: %d->%d",
2562                 iom->status, iomux_conn_disconnected);
2563         }
2564         /*------ DEBUG LOG END ------*/
2565         iom->status = iomux_conn_disconnected;
2566         /*-------- DEBUG LOG --------*/
2567         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2568             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,233,
2569                 "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2570                 "return_value: 1");
2571         }
2572         /*------ DEBUG LOG END ------*/
2573         return 1;
2574     default:
2575         // reading data is finished
2576         /*-------- DEBUG LOG --------*/
2577         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2578             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,239,
2579                 "iom->status change: %d->%d",
2580                 iom->status, iomux_conn_received);
2581         }
2582         /*------ DEBUG LOG END ------*/
2583         iom->status = iomux_conn_received;
2584         break;
2585     }
2586     
2587     // register reveive information for QoS to server
2588     if( source_fd == conn->ciom->fd ){
2589         l7vs_conn_QoS_recvsize_register( conn, ret, QOS_UP );
2590     }
2591     // register reveive information for QoS to client
2592     if( source_fd == conn->riom->fd ){
2593         l7vs_conn_QoS_recvsize_register( conn, ret, QOS_DOWN );
2594     }
2595     // copy to conn_buffer
2596     memcpy(conn->cldata + conn->cldata_len, read_buf, ret);
2597     conn->cldata_len += ret;
2598     conn->cldata[conn->cldata_len] = '\0';
2599
2600     /*-------- DEBUG LOG --------*/
2601     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2602         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,240,
2603             "out_function: static int l7vs_conn_recv(struct l7vs_iomux *iom, int source_fd) "
2604             "return_value: 1");
2605     }
2606     /*------ DEBUG LOG END ------*/
2607     return 1;
2608 }
2609
2610 /*!
2611  * pre-read whether next data exists
2612  *
2613  * @param[in]   iom         connection iomux
2614  * @param[in]   source_fd   source file description
2615  * @return      status
2616  * @retval      0       failed
2617  * @retval      1       succeed
2618  */
2619 static int
2620 l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd)
2621 {
2622     /*-------- DEBUG LOG --------*/
2623     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2624         char iom_str[DEBUG_STR_LEN] = {0};
2625         l7vs_iomux_c_str(iom_str, iom);
2626         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,241,
2627             "in_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2628             "iom=%s: "
2629             "source_fd=%d",
2630             iom_str, source_fd);
2631     }
2632     /*------ DEBUG LOG END ------*/
2633     int preread_ret = 0;
2634     char preread_buf[1] = {0};
2635
2636     if (!iom) {
2637         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,69, "error / iom is null");
2638         /*-------- DEBUG LOG --------*/
2639         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2640             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,242,
2641                 "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2642                 "return_value: 0");
2643         }
2644         /*------ DEBUG LOG END ------*/
2645         return 0;
2646     }
2647
2648     if (-1 == source_fd) {
2649         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,70, "error / source fd is not specified");
2650         /*-------- DEBUG LOG --------*/
2651         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2652             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,243,
2653                 "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2654                 "return_value: 0");
2655         }
2656         /*------ DEBUG LOG END ------*/
2657         return 0;
2658     }
2659
2660     if (iomux_conn_receiving != iom->status) {
2661         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,71, "error / invalid status(%d)", iom->status);
2662         /*-------- DEBUG LOG --------*/
2663         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2664             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,244,
2665                 "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2666                 "return_value: 0");
2667         }
2668         /*------ DEBUG LOG END ------*/
2669         return 0;
2670     }
2671
2672     /*-------- DEBUG LOG --------*/
2673     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2674         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,245,
2675             "recv param: source_fd=%d: len=1: flags=MSG_PEEK",
2676             source_fd);
2677     }
2678     /*------ DEBUG LOG END ------*/
2679     preread_ret = recv(source_fd, preread_buf, 1, MSG_PEEK);
2680     /*-------- DEBUG LOG --------*/
2681     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2682         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,246,
2683             "recv result: preread_ret=%d",
2684             preread_ret);
2685     }
2686     /*------ DEBUG LOG END ------*/
2687     /*-------- DEBUG LOG --------*/
2688     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2689         char recv_data[DEBUG_STR_LEN] = {0};
2690         l7vs_conn_dump_data(recv_data, preread_buf, preread_ret);
2691         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,247,
2692             "recv data: %s",
2693             recv_data);
2694     }
2695     /*------ DEBUG LOG END ------*/
2696     switch (preread_ret) {
2697     case -1:
2698         if (EAGAIN != errno) {
2699             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,13, "error / recv error(%s)", strerror(errno));
2700             /*-------- DEBUG LOG --------*/
2701             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2702                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,248,
2703                     "iom->status change: %d->%d",
2704                     iom->status, iomux_conn_receive_error);
2705             }
2706             /*------ DEBUG LOG END ------*/
2707             iom->status = iomux_conn_receive_error;
2708             /*-------- DEBUG LOG --------*/
2709             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2710                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,249,
2711                     "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2712                     "return_value: 0");
2713             }
2714             /*------ DEBUG LOG END ------*/
2715             return 0;
2716         }
2717         // finished reading all data
2718         /*-------- DEBUG LOG --------*/
2719         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2720             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,250,
2721                 "iom->status change: %d->%d",
2722                 iom->status, iomux_conn_received);
2723         }
2724         /*------ DEBUG LOG END ------*/
2725         iom->status = iomux_conn_received;
2726         break;
2727     case 0:
2728         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2729             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,251, "peer disconnected");
2730         }
2731         /*-------- DEBUG LOG --------*/
2732         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2733             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,252,
2734                 "iom->status change: %d->%d",
2735                 iom->status, iomux_conn_disconnected);
2736         }
2737         /*------ DEBUG LOG END ------*/
2738         iom->status =  iomux_conn_disconnected;
2739         break;
2740     case 1:
2741         // the data that should be read remains
2742         // status does not change
2743         break;
2744     default:
2745         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_NETWORK,37, "error / preread error");
2746         /*-------- DEBUG LOG --------*/
2747         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2748             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,253,
2749                 "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2750                 "return_value: 0");
2751         }
2752         /*------ DEBUG LOG END ------*/
2753         return 0;
2754     }
2755     /*-------- DEBUG LOG --------*/
2756     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2757         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,254,
2758             "out_function: static int l7vs_conn_preread(struct l7vs_iomux *iom, int source_fd) "
2759             "return_value: 1");
2760     }
2761     /*------ DEBUG LOG END ------*/
2762     return 1;
2763 }
2764
2765 /*!
2766  * send data
2767  *
2768  * @param[in]   iom         connection_iomux
2769  * @param[in]   dest_fd     the filedescriptor to be write
2770  * @return      status
2771  * @retval      0       failed 
2772  * @retval      1       succeed
2773  */
2774 static int
2775 l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd)
2776 {
2777     /*-------- DEBUG LOG --------*/
2778     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2779         char iom_str[DEBUG_STR_LEN] = {0};
2780         l7vs_iomux_c_str(iom_str, iom);
2781         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,255,
2782             "in_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2783             "iom=%s: "
2784             "dest_fd=%d",
2785             iom_str, dest_fd);
2786     }
2787     /*------ DEBUG LOG END ------*/
2788
2789     int ret = 0;
2790     struct l7vs_conn *conn = NULL;
2791     char *newbuf = NULL;
2792     size_t sent_len = 0;
2793
2794     if (!iom) {
2795         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,72, "error / iom is null");
2796         /*-------- DEBUG LOG --------*/
2797         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2798             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,256,
2799                 "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2800                 "return_value: 0");
2801         }
2802         /*------ DEBUG LOG END ------*/
2803         return 0;
2804     }
2805
2806     if (-1 == dest_fd) {
2807         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,73, "error / dest fd is not specified");
2808         /*-------- DEBUG LOG --------*/
2809         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2810             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,257,
2811                 "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2812                 "return_value: 0");
2813         }
2814         /*------ DEBUG LOG END ------*/
2815         return 0;
2816     }
2817
2818     if (iomux_conn_sending != iom->status &&
2819         iomux_conn_sending_busy != iom->status) {
2820         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,74, "error / invalid status(%d)", iom->status);
2821         /*-------- DEBUG LOG --------*/
2822         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2823             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,258,
2824                 "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2825                 "return_value: 0");
2826         }
2827         /*------ DEBUG LOG END ------*/
2828         return 0;
2829     }
2830
2831     conn = (struct l7vs_conn *)iom->data;
2832     /*-------- DEBUG LOG --------*/
2833     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2834         char conn_str[DEBUG_STR_LEN] = {0};
2835         l7vs_conn_c_str(conn_str, conn);
2836         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,259,
2837             "pointer_assign: conn=%s",
2838             conn_str);
2839     }
2840     /*------ DEBUG LOG END ------*/
2841
2842     /*-------- DEBUG LOG --------*/
2843     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2844         char send_data[DEBUG_STR_LEN] = {0};
2845         l7vs_conn_dump_data(send_data, conn->cldata, conn->cldata_len);
2846         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,260,
2847             "send data: %s",
2848             send_data);
2849     }
2850     /*------ DEBUG LOG END ------*/
2851     // write the data
2852     /*-------- DEBUG LOG --------*/
2853     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2854         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,261,
2855             "send param: dest_fd=%d: len=%zu: flags=MSG_NOSIGNAL",
2856             dest_fd, conn->cldata_len);
2857     }
2858     /*------ DEBUG LOG END ------*/
2859     ret = send(dest_fd, conn->cldata, conn->cldata_len, MSG_NOSIGNAL);
2860     /*-------- DEBUG LOG --------*/
2861     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2862         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,262,
2863             "send result: ret=%d",
2864             ret);
2865     }
2866     /*------ DEBUG LOG END ------*/
2867     if (0 > ret) {
2868         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,14, "error / send error(%s)", strerror(errno));
2869         iom->status = iomux_conn_send_error;
2870         /*-------- DEBUG LOG --------*/
2871         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2872             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,263,
2873                 "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2874                 "return_value: 0");
2875         }
2876         /*------ DEBUG LOG END ------*/
2877         return 0;
2878     }
2879     sent_len = ret;
2880     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2881         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,264, "sent %zu bytes", sent_len);
2882     }
2883
2884     // decide the status
2885     if (conn->cldata_len == sent_len) {
2886         // finished sending all data
2887         if (iomux_conn_sending == iom->status) {
2888             /*-------- DEBUG LOG --------*/
2889             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2890                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,265,
2891                     "iom->status change: %d->%d",
2892                     iom->status, iomux_conn_sent);
2893             }
2894             /*------ DEBUG LOG END ------*/
2895             iom->status = iomux_conn_sent;
2896         } else {
2897             /*-------- DEBUG LOG --------*/
2898             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2899                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,266,
2900                     "iom->status change: %d->%d",
2901                     iom->status, iomux_conn_sent_busy);
2902             }
2903             /*------ DEBUG LOG END ------*/
2904             iom->status = iomux_conn_sent_busy;
2905         }
2906         //cldata memory realloc
2907         conn->cldata_len = 0;
2908         conn->cldata_bufsize = l7vs_conn_read_bufsize;
2909         newbuf = (char *)malloc(conn->cldata_bufsize);
2910         if (!newbuf) {
2911             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,12, "error / malloc failed");
2912             iom->status = iomux_conn_send_error;
2913             /*-------- DEBUG LOG --------*/
2914             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2915                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,267,
2916                     "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2917                     "return_value: 0");
2918             }
2919             /*------ DEBUG LOG END ------*/
2920             return 0;
2921         }
2922         free(conn->cldata);
2923         conn->cldata = newbuf;
2924         memset(conn->cldata, 0, l7vs_conn_read_bufsize);
2925     }
2926     else {
2927         // shift data for next sending
2928         newbuf = (char *)malloc((conn->cldata_len - sent_len) + 1);
2929         if (!newbuf) {
2930             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,13, "error / malloc failed");
2931             /*-------- DEBUG LOG --------*/
2932             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2933                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,268,
2934                     "iom->status change: %d->%d",
2935                     iom->status, iomux_conn_send_error);
2936             }
2937             /*------ DEBUG LOG END ------*/
2938             iom->status = iomux_conn_send_error;
2939             /*-------- DEBUG LOG --------*/
2940             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2941                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,269,
2942                     "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2943                     "return_value: 0");
2944             }
2945             /*------ DEBUG LOG END ------*/
2946             return 0;
2947         }
2948         memcpy(newbuf, (conn->cldata + sent_len), conn->cldata_len - sent_len);
2949         free(conn->cldata);
2950         conn->cldata = newbuf;
2951         conn->cldata_len -= sent_len;
2952         conn->cldata[conn->cldata_len] = '\0';
2953
2954         // the data that should be sent remains, status does not change
2955     }
2956
2957     /*-------- DEBUG LOG --------*/
2958     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2959         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,270,
2960             "out_function: static int l7vs_conn_send(struct l7vs_iomux *iom, int dest_fd) "
2961             "return_value: 1");
2962     }
2963     /*------ DEBUG LOG END ------*/
2964     return 1;
2965
2966 }
2967
2968 /*!
2969  * connect to real server
2970  *
2971  * @param[in]   conn    connection
2972  * @param[in]   dest    destination
2973  * @return      status
2974  * @retval      0       failed 
2975  * @retval      1       succeed
2976  */
2977 int
2978 l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest)
2979 {
2980     /*-------- DEBUG LOG --------*/
2981     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
2982         char conn_str[DEBUG_STR_LEN] = {0};
2983         char dest_str[DEBUG_STR_LEN] = {0};
2984         l7vs_conn_c_str(conn_str, conn);
2985         l7vs_dest_c_str(dest_str, dest);
2986         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,271,
2987             "in_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
2988             "conn=%s: "
2989             "dest=%s",
2990             conn_str, dest_str);
2991     }
2992     /*------ DEBUG LOG END ------*/
2993
2994         int s;
2995         int stype;
2996         int flags;
2997         int ret;
2998     enum iomaction action;
2999
3000     if (!conn) {
3001         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,75, "error / conn is null");
3002         /*-------- DEBUG LOG --------*/
3003         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3004             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,272,
3005                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3006                 "return_value: 0");
3007         }
3008         /*------ DEBUG LOG END ------*/
3009         return 0;
3010     }
3011     if (!dest) {
3012         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,76, "error / dest is null");
3013         /*-------- DEBUG LOG --------*/
3014         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3015             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,273,
3016                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3017                 "return_value: 0");
3018         }
3019         /*------ DEBUG LOG END ------*/
3020         return 0;
3021     }
3022
3023         switch (conn->proto) {
3024         case IPPROTO_TCP:
3025                 stype = SOCK_STREAM;
3026                 break;
3027         case IPPROTO_UDP:
3028                 stype = SOCK_DGRAM;
3029                 break;
3030         default:
3031         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,15, "error / unknown socket type");
3032         /*-------- DEBUG LOG --------*/
3033         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3034             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,274,
3035                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3036                 "return_value: 0");
3037         }
3038         /*------ DEBUG LOG END ------*/
3039                 return 0;
3040         }
3041
3042     /*-------- DEBUG LOG --------*/
3043     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3044         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,275,
3045             "socket param: family=PF_INET: type=%d: protocol=%d",
3046             stype, conn->proto);
3047     }
3048     /*------ DEBUG LOG END ------*/
3049         s = socket(PF_INET, stype, conn->proto);  
3050         if (0 > s) {
3051         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,16, "error / socket error(%s)", strerror(errno));
3052         /*-------- DEBUG LOG --------*/
3053         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3054             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,276,
3055                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3056                 "return_value: 0");
3057         }
3058         /*------ DEBUG LOG END ------*/
3059                 return 0;
3060         }
3061         
3062     /*-------- DEBUG LOG --------*/
3063     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3064         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,277,
3065             "fnctl param: s=%d: cmd=F_GETFL: flags=0",
3066             s);
3067     }
3068     /*------ DEBUG LOG END ------*/
3069         flags = fcntl(s, F_GETFL, 0);
3070         if (0 > flags) {
3071         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,17, "error / fcntl(s=%d,F_GETFL) error(%s)", s,strerror(errno));
3072                 close(s);
3073         /*-------- DEBUG LOG --------*/
3074         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3075             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,278,
3076                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3077                 "return_value: 0");
3078         }
3079         /*------ DEBUG LOG END ------*/
3080                 return 0;
3081         }
3082     /*-------- DEBUG LOG --------*/
3083     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3084         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,279,
3085             "fnctl result: flags=%d",
3086             flags);
3087     }
3088     /*------ DEBUG LOG END ------*/
3089
3090     /*-------- DEBUG LOG --------*/
3091     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3092         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,280,
3093             "fnctl param: s=%d: cmd=F_SETFL: flags=%d",
3094             s, (flags | O_NONBLOCK));
3095     }
3096     /*------ DEBUG LOG END ------*/
3097         flags = fcntl(s, F_SETFL, flags | O_NONBLOCK);
3098         if (0 > flags) {
3099         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,18, "error / fcntl(s=%d,F_SETFL) error(%s)", s,strerror(errno));
3100                 close(s);
3101         /*-------- DEBUG LOG --------*/
3102         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3103             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,281,
3104                 "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3105                 "return_value: 0");
3106         }
3107         /*------ DEBUG LOG END ------*/
3108                 return 0;
3109         }
3110     /*-------- DEBUG LOG --------*/
3111     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3112         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,282,
3113             "fnctl result: flags=%d",
3114             flags);
3115     }
3116     /*------ DEBUG LOG END ------*/
3117
3118         if (conn->cmss > 0) {
3119         /*-------- DEBUG LOG --------*/
3120         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3121             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,283,
3122                 "setsockopt param: s=%d: level=IPROTO_TCP: optname=TCP_MAXSEG: optval=%d: "
3123                 "len=%zu",
3124                 s, conn->cmss, sizeof(int));
3125         }
3126         /*------ DEBUG LOG END ------*/
3127                 ret = setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &conn->cmss,
3128                                  sizeof(int));
3129                 if (ret < 0) {
3130             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,19, "error / setsockopt(TCP_MAXSEG) error(%s)", strerror(errno));
3131                 }
3132         /*-------- DEBUG LOG --------*/
3133         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3134             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,284,
3135                 "setsockopt result: ret=%d: len=%zu",
3136                 ret, sizeof(int));
3137         }
3138         /*------ DEBUG LOG END ------*/
3139         }
3140
3141     /*-------- DEBUG LOG --------*/
3142     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3143         char addr_str[DEBUG_STR_LEN] = {0};
3144         l7vs_conn_sockaddr_in_c_str(addr_str, &dest->addr);
3145         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,285,
3146             "connect param: s=%d: dest->addr=%s: len=%zu",
3147             s, addr_str, sizeof(struct sockaddr_in));
3148     }
3149     /*------ DEBUG LOG END ------*/
3150         ret = connect(s, (struct sockaddr *)&dest->addr,
3151                       sizeof(struct sockaddr_in)); 
3152         if (0 > ret) {
3153                 if (errno != EINPROGRESS) {
3154             LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,20, "error / connect error(%s)", strerror(errno));
3155                         close(s);
3156             /*-------- DEBUG LOG --------*/
3157             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3158                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,286,
3159                     "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3160                     "return_value: 0");
3161             }
3162             /*------ DEBUG LOG END ------*/
3163                         return 0;
3164                 }
3165     }
3166     /*-------- DEBUG LOG --------*/
3167     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3168         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,287,
3169             "connect result: ret=%d",
3170             ret);
3171     }
3172     /*------ DEBUG LOG END ------*/
3173     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3174         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,288, "dest %p nactive %d->%d",
3175             dest, dest->nactive,
3176             dest->nactive + 1);
3177     }
3178
3179     action = iom_write;
3180     dest->nactive++;   
3181     conn->dest = dest;
3182     /*-------- DEBUG LOG --------*/
3183     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3184         char dest_str[DEBUG_STR_LEN] = {0};
3185         l7vs_dest_c_str(dest_str, conn->dest);
3186         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,289,
3187             "pointer_assign: conn->dest=%s",
3188             dest_str);
3189     }
3190     /*------ DEBUG LOG END ------*/
3191     conn->riom->fd = s;
3192     conn->riom->callback = l7vs_conn_rs_callback;
3193     /*-------- DEBUG LOG --------*/
3194     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3195         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,290,
3196             "pointer_assign: conn->riom->callback=%p",
3197             conn->riom->callback);
3198     }
3199     /*------ DEBUG LOG END ------*/
3200     conn->riom->data = conn;
3201     /*-------- DEBUG LOG --------*/
3202     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3203         char conn_str[DEBUG_STR_LEN] = {0};
3204         l7vs_conn_c_str(conn_str, conn);
3205         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,291,
3206             "pointer_assign: conn->riom->data=%s",
3207             conn_str);
3208     }
3209     /*------ DEBUG LOG END ------*/
3210     l7vs_iomux_add(conn->riom, action);
3211
3212     /*-------- DEBUG LOG --------*/
3213     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3214         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,292,
3215             "out_function: int l7vs_conn_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3216             "return_value: 1");
3217     }
3218
3219     if ( dest ){
3220                 /*-------- DEBUG LOG --------*/
3221         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3222                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,341,
3223                 "RealServer Connecting Count : nactive is %d",
3224                 dest->nactive);
3225         }
3226         /*-------- DEBUG LOG --------*/
3227
3228         /*-------- INFO LOG (Access Log) --------*/
3229         if (LOG_LV_INFO >= logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3230             char addr_str_tmp[ADDR_STR_LEN] = {0};
3231             memcpy(addr_str_tmp, inet_ntoa(conn->caddr.sin_addr), ADDR_STR_LEN);
3232             LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK,342,
3233                 "[[AccessLog] (SRC)%s:%d -> (DST)%s:%d ]",
3234                 addr_str_tmp,
3235                 ntohs(conn->caddr.sin_port),
3236                 inet_ntoa(conn->dest->addr.sin_addr),
3237                 ntohs(conn->dest->addr.sin_port));
3238         }
3239         /*------ INFO LOG END (Access Log) ------*/
3240     }
3241
3242     /*------ DEBUG LOG END ------*/
3243         return 1;
3244 }
3245
3246 /*!
3247  * close client socket 
3248  *
3249  * @param[in]   conn    connection
3250  * @return      void 
3251  */
3252 void
3253 l7vs_conn_close_csock(struct l7vs_conn *conn)
3254 {
3255     /*-------- DEBUG LOG --------*/
3256     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3257         char conn_str[DEBUG_STR_LEN] = {0};
3258         l7vs_conn_c_str(conn_str, conn);
3259         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,293,
3260             "in_function: void l7vs_conn_close_csock(struct l7vs_conn *conn) "
3261             "conn=%s",
3262             conn_str);
3263     }
3264     /*------ DEBUG LOG END ------*/
3265
3266     if (!conn) {
3267         /*-------- DEBUG LOG --------*/
3268         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3269             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,294,
3270                 "out_function: void l7vs_conn_close_csock(struct l7vs_conn *conn) "
3271                 "return_value: void");
3272         }
3273         /*------ DEBUG LOG END ------*/
3274         return;
3275     }
3276     if (!conn->ciom) {
3277         /*-------- DEBUG LOG --------*/
3278         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3279             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,295,
3280                 "out_function: void l7vs_conn_close_csock(struct l7vs_conn *conn) "
3281                 "return_value: void");
3282         }
3283         /*------ DEBUG LOG END ------*/
3284         return;
3285     }
3286     if (-1 == conn->ciom->fd) {
3287         /*-------- DEBUG LOG --------*/
3288         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3289             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,296,
3290                 "out_function: void l7vs_conn_close_csock(struct l7vs_conn *conn) "
3291                 "return_value: void");
3292         }
3293         /*------ DEBUG LOG END ------*/
3294         return;
3295     }
3296
3297     l7vs_iomux_remove(conn->ciom);
3298     /*-------- DEBUG LOG --------*/
3299     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3300         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,297,
3301             "close: conn->ciom->fd=%d",
3302             conn->ciom->fd);
3303     }
3304     /*------ DEBUG LOG END ------*/
3305     close(conn->ciom->fd);
3306     conn->ciom->fd = -1;
3307
3308     /*-------- DEBUG LOG --------*/
3309     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3310         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,298,
3311             "out_function: void l7vs_conn_close_csock(struct l7vs_conn *conn) "
3312             "return_value: void");
3313     }
3314     /*------ DEBUG LOG END ------*/
3315 }
3316
3317 /*!
3318  * close real server socket
3319  *
3320  * @param[in]   conn    connection
3321  * @return      void 
3322  */
3323 void
3324 l7vs_conn_close_rsock(struct l7vs_conn *conn)
3325 {
3326     /*-------- DEBUG LOG --------*/
3327     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3328         char conn_str[DEBUG_STR_LEN] = {0};
3329         l7vs_conn_c_str(conn_str, conn);
3330         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,299,
3331             "in_function: void l7vs_conn_close_rsock(struct l7vs_conn *conn) "
3332             "conn=%s",
3333             conn_str);
3334     }
3335     /*------ DEBUG LOG END ------*/
3336
3337     if (!conn) {
3338         /*-------- DEBUG LOG --------*/
3339         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3340             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,300,
3341                 "out_function: void l7vs_conn_close_rsock(struct l7vs_conn *conn) "
3342                 "return_value: void");
3343         }
3344         /*------ DEBUG LOG END ------*/
3345         return;
3346     }
3347     if (!conn->riom) {
3348         /*-------- DEBUG LOG --------*/
3349         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3350             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,301,
3351                 "out_function: void l7vs_conn_close_rsock(struct l7vs_conn *conn) "
3352                 "return_value: void");
3353         }
3354         /*------ DEBUG LOG END ------*/
3355         return;
3356     }
3357     if (-1 == conn->riom->fd) {
3358         /*-------- DEBUG LOG --------*/
3359         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3360             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,302,
3361                 "out_function: void l7vs_conn_close_rsock(struct l7vs_conn *conn) "
3362                 "return_value: void");
3363         }
3364         /*------ DEBUG LOG END ------*/
3365         return;
3366     }
3367
3368     if (conn->dest) {
3369         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3370             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,303, "dest %p nactive %d->%d",
3371                 conn->dest, conn->dest->nactive,
3372                 conn->dest->nactive - 1);
3373         }
3374         conn->dest->nactive--;
3375         conn->dest->ninact++;
3376         if(conn->dest->ninact == INT_MAX) {
3377             conn->dest->ninact = 0;
3378         }
3379
3380         /*-------- DEBUG LOG --------*/
3381         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3382                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,343,
3383                 "RealServer Connected Count : ninact is %d",
3384                 conn->dest->ninact);
3385         }
3386         /*------ DEBUG LOG END ------*/
3387     }
3388
3389     l7vs_iomux_remove(conn->riom);
3390     /*-------- DEBUG LOG --------*/
3391     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3392         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,304,
3393             "close: conn->riom->fd=%d",
3394             conn->riom->fd);
3395     }
3396     /*------ DEBUG LOG END ------*/
3397     close(conn->riom->fd);
3398     conn->riom->fd = -1;
3399
3400     /*-------- DEBUG LOG --------*/
3401     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3402         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,305,
3403             "out_function: void l7vs_conn_close_rsock(struct l7vs_conn *conn) "
3404             "return_value: void");
3405     }
3406     /*------ DEBUG LOG END ------*/
3407 }
3408
3409 /*!
3410  * confirmation of whether conn is closed
3411  *
3412  * @param[in]   conn    connection
3413  * @return      closed or not
3414  * @retval      0       not closed 
3415  * @retval      1       closed
3416  */
3417 int
3418 l7vs_conn_closed(struct l7vs_conn *conn)
3419 {
3420     /*-------- DEBUG LOG --------*/
3421     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3422         char conn_str[DEBUG_STR_LEN] = {0};
3423         l7vs_conn_c_str(conn_str, conn);
3424         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,306,
3425             "in_function: int l7vs_conn_closed(struct l7vs_conn *conn) "
3426             "conn=%s",
3427             conn_str);
3428     }
3429     /*------ DEBUG LOG END ------*/
3430
3431     if (!conn) {
3432         /*-------- DEBUG LOG --------*/
3433         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3434             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,307,
3435                 "out_function: int l7vs_conn_closed(struct l7vs_conn *conn) "
3436                 "return_value: 1");
3437         }
3438         /*------ DEBUG LOG END ------*/
3439         return 1;
3440     }
3441     if ((conn->ciom && -1 != conn->ciom->fd) || (conn->riom && -1 != conn->riom->fd)) {
3442         /*-------- DEBUG LOG --------*/
3443         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3444             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,308,
3445                 "out_function: int l7vs_conn_closed(struct l7vs_conn *conn) "
3446                 "return_value: 0");
3447         }
3448         /*------ DEBUG LOG END ------*/
3449         return 0;
3450     } else {
3451         /*-------- DEBUG LOG --------*/
3452         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3453             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,309,
3454                 "out_function: int l7vs_conn_closed(struct l7vs_conn *conn) "
3455                 "return_value: 1");
3456         }
3457         /*------ DEBUG LOG END ------*/
3458         return 1;
3459     }
3460 }
3461
3462 /*!
3463  * Change connection to specified destination (to real-server or sorry-server).
3464  *
3465  * @param[in]   *conn   connection pointer
3466  * @param[in]   *dest   destination pointer
3467  * @return      int     change connection result 0=NG, 1=OK
3468  */
3469 static int l7vs_conn_change_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest)
3470 {
3471     /*-------- DEBUG LOG --------*/
3472     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3473         char conn_str[DEBUG_STR_LEN] = {0};
3474         char dest_str[DEBUG_STR_LEN] = {0};
3475         l7vs_conn_c_str(conn_str, conn);
3476         l7vs_dest_c_str(dest_str, dest);
3477         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,310,
3478             "in_function: static int l7vs_conn_change_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3479             "conn=%s: "
3480             "dest=%s",
3481             conn_str, dest_str);
3482     }
3483     /*------ DEBUG LOG END ------*/
3484
3485     int ret;
3486
3487     if (!conn) {
3488         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,77, "error / conn is null");
3489         /*-------- DEBUG LOG --------*/
3490         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3491             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,311,
3492                 "out_function: static int l7vs_conn_change_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3493                 "return_value: 0");
3494         }
3495         /*------ DEBUG LOG END ------*/
3496         return 0;
3497     }
3498     if (!dest) {
3499         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_PROGRAM,78, "error / dest is null");
3500         /*-------- DEBUG LOG --------*/
3501         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3502             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,312,
3503                 "out_function: static int l7vs_conn_change_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3504                 "return_value: 0");
3505         }
3506         /*------ DEBUG LOG END ------*/
3507         return 0;
3508     }
3509     // save old destination
3510     conn->old_dest = conn->dest;
3511     /*-------- DEBUG LOG --------*/
3512     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3513         char old_dest_str[DEBUG_STR_LEN] = {0};
3514         l7vs_dest_c_str(old_dest_str, conn->old_dest);
3515         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,313,
3516             "pointer_assign: conn->old_dest=%s",
3517             old_dest_str);
3518     }
3519     /*------ DEBUG LOG END ------*/
3520     // close real-server connection
3521     l7vs_conn_close_rsock(conn);
3522     // connect to new destination
3523     ret = l7vs_conn_connect_rs(conn, dest);
3524
3525     /*-------- DEBUG LOG --------*/
3526     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3527         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,314,
3528             "out_function: static int l7vs_conn_change_connect_rs(struct l7vs_conn *conn, struct l7vs_dest *dest) "
3529             "return_value: %d",
3530             ret);
3531     }
3532     /*------ DEBUG LOG END ------*/
3533     return ret;
3534 }
3535
3536 /*!
3537  * Judges from the data size received last time and recieve-interval
3538  *
3539  * @param[in]   *conn       connection pointer
3540  * @param[in]   direction   traffic direction
3541  * @return      int         permitte for recv function call 0=NG(not permitted), 1=OK(permitted)
3542  */
3543 static int
3544 l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction )
3545 {
3546     /*-------- DEBUG LOG --------*/
3547     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3548         char conn_str[DEBUG_STR_LEN] = {0};
3549         l7vs_conn_c_str(conn_str, conn);
3550         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,315,
3551             "in_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3552             "conn=%s, direction=%d",
3553             conn_str, direction);
3554     }
3555     /*------ DEBUG LOG END ------*/
3556
3557     if (!conn) {
3558         /*-------- DEBUG LOG --------*/
3559         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3560             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,316,
3561                 "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3562                 "return_value: 1");
3563         }
3564         /*------ DEBUG LOG END ------*/
3565         return 1;
3566     }
3567     if (!conn->srv) {
3568         /*-------- DEBUG LOG --------*/
3569         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3570             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,317,
3571                 "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3572                 "return_value: 1");
3573         }
3574         /*------ DEBUG LOG END ------*/
3575         return 1;
3576     }
3577
3578     struct timeval CurrTime;
3579     gettimeofday( &CurrTime, NULL );
3580     /*-------- DEBUG LOG --------*/
3581     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3582         char time_str[DEBUG_STR_LEN] = {0};
3583         snprintf(time_str, DEBUG_STR_LEN,
3584             "timeval="
3585             "{tv_sec=%ld: "
3586             "tv_usec=%ld}"
3587             , CurrTime.tv_sec
3588             , CurrTime.tv_usec);
3589         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,339,
3590             "gettimeofday result: CurrTime=%s",
3591             time_str);
3592     }
3593     /*------ DEBUG LOG END ------*/
3594
3595     unsigned long long cur_recvtime = (CurrTime.tv_sec * 1000000ULL + CurrTime.tv_usec) / throughput_interval;
3596     l7vs_service_update_throughput(conn->srv, cur_recvtime);
3597
3598     switch (direction) {
3599     case QOS_UP:
3600         //QoS Control check : to server
3601         conn->srv->throughput_to_server = conn->srv->cur_recvsize_from_client * 1000000ULL / throughput_interval;
3602         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3603             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,323, "QoS threshold to server:%lld ", conn->srv->qos_threshold_up);
3604             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,324, "(current throughput:%lld)", conn->srv->throughput_to_server);
3605         }
3606         if( (conn->srv->qos_threshold_up) && (conn->srv->throughput_to_server + l7vs_conn_read_bufsize > conn->srv->qos_threshold_up) ){
3607             if (conn->srv->qos_up_flag == 0) {
3608                 LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK_QOS,1, "Start QoS traffic control to server.");
3609                 conn->srv->qos_up_flag = 1;
3610             }
3611             /*-------- DEBUG LOG --------*/
3612             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3613                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,326,
3614                     "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3615                     "return_value: 0");
3616             }
3617             /*------ DEBUG LOG END ------*/
3618             return 0;
3619         }
3620         if (conn->srv->qos_up_flag == 1) {
3621             LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK_QOS,2, "Stop QoS traffic control to server.");
3622             conn->srv->qos_up_flag = 0;
3623         }
3624         break;
3625     case QOS_DOWN:
3626         //QoS Control check : to client
3627         conn->srv->throughput_to_client = conn->srv->cur_recvsize_from_server * 1000000ULL / throughput_interval;
3628         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3629             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,323, "QoS threshold to client:%lld ", conn->srv->qos_threshold_down);
3630             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,324, "(current throughput:%lld)", conn->srv->throughput_to_client);
3631         }
3632         if( (conn->srv->qos_threshold_down) && (conn->srv->throughput_to_client + l7vs_conn_read_bufsize > conn->srv->qos_threshold_down) ){
3633             if (conn->srv->qos_down_flag == 0) {
3634                 LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK_QOS,3, "Start QoS traffic control to client.");
3635                 conn->srv->qos_down_flag = 1;
3636             }
3637             /*-------- DEBUG LOG --------*/
3638             if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3639                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,326,
3640                     "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3641                     "return_value: 0");
3642             }
3643             /*------ DEBUG LOG END ------*/
3644             return 0;
3645         }
3646         if (conn->srv->qos_down_flag == 1) {
3647             LOGGER_PUT_LOG_INFO(LOG_CAT_L7VSD_NETWORK_QOS,4, "Stop QoS traffic control to client.");
3648             conn->srv->qos_down_flag = 0;
3649         }
3650         break;
3651     default:
3652         /*-------- DEBUG LOG --------*/
3653         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3654             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,317,
3655                 "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn, int direction ) "
3656                 "return_value: 1");
3657         }
3658         /*------ DEBUG LOG END ------*/
3659         return 1;
3660     }
3661
3662     /*-------- DEBUG LOG --------*/
3663     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3664         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,335,
3665             "out_function: static int l7vs_conn_QoS_control( struct l7vs_conn *conn ) "
3666             "return_value: 1");
3667     }
3668     /*------ DEBUG LOG END ------*/
3669     return 1;
3670 }
3671
3672 /*!
3673  * Regsiter recive time and recieved data size
3674  *
3675  * @param[in]   *conn       connection pointer
3676  * @param[in]   in_recvsize recieved size
3677  * @param[in]   direction   traffic direction
3678  * @return      void 
3679  */
3680 static void
3681 l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize, int direction )
3682 {
3683     /*-------- DEBUG LOG --------*/
3684     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3685         char conn_str[DEBUG_STR_LEN] = {0};
3686         l7vs_conn_c_str(conn_str, conn);
3687         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,336,
3688             "in_function: static void l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize ) "
3689             "conn=%s: "
3690             "in_recvsize=%zu",
3691             conn_str, in_recvsize);
3692     }
3693     /*------ DEBUG LOG END ------*/
3694
3695     if (!conn) {
3696         /*-------- DEBUG LOG --------*/
3697         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3698             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,337,
3699                 "out_function: static void l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize ) "
3700                 "return_value: void");
3701         }
3702         /*------ DEBUG LOG END ------*/
3703         return;
3704     }
3705     if (!conn->srv) {
3706         /*-------- DEBUG LOG --------*/
3707         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3708             LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,338,
3709                 "out_function: static void l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize ) "
3710                 "return_value: void");
3711         }
3712         /*------ DEBUG LOG END ------*/
3713         return;
3714     }
3715     struct timeval CurrTime;
3716     gettimeofday( &CurrTime, NULL );
3717     /*-------- DEBUG LOG --------*/
3718     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3719         char time_str[DEBUG_STR_LEN] = {0};
3720         snprintf(time_str, DEBUG_STR_LEN,
3721             "timeval="
3722             "{tv_sec=%ld: "
3723             "tv_usec=%ld}"
3724             , CurrTime.tv_sec
3725             , CurrTime.tv_usec);
3726         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,339,
3727             "gettimeofday result: CurrTime=%s",
3728             time_str);
3729     }
3730     /*------ DEBUG LOG END ------*/
3731
3732     int throughput_interval = BPS_DEFAULT_INTERVAL;
3733     if ( parameter_is_int_exist( PARAM_COMP_L7VSD, "calc_throughput_interval" ) ) {
3734         throughput_interval = parameter_get_int_value( PARAM_COMP_L7VSD, "calc_throughput_interval" );
3735     }
3736     unsigned long long cur_recvtime = (CurrTime.tv_sec * 1000000ULL + CurrTime.tv_usec) / throughput_interval;
3737     l7vs_service_update_throughput(conn->srv, cur_recvtime);
3738
3739     switch (direction) {
3740     case QOS_UP:
3741         conn->srv->cur_recvsize_from_client += in_recvsize;
3742         break;
3743     case QOS_DOWN:
3744         conn->srv->cur_recvsize_from_server += in_recvsize;
3745         break;
3746     default:
3747         break;
3748     }
3749
3750     /*-------- DEBUG LOG --------*/
3751     if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_NETWORK)) {
3752         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_NETWORK,340,
3753             "out_function: static void l7vs_conn_QoS_recvsize_register( struct l7vs_conn *conn, const size_t in_recvsize ) "
3754             "return_value: void");
3755     }
3756     /*------ DEBUG LOG END ------*/
3757 }
3758