diff --git a/Platform/modules/trace-relay/trace_init.c b/Platform/modules/trace-relay/trace_init.c index 937290472..f466de248 100755 --- a/Platform/modules/trace-relay/trace_init.c +++ b/Platform/modules/trace-relay/trace_init.c @@ -53,6 +53,7 @@ static int trace_rcv_policy(struct sk_buff *skb, struct nlmsghdr *nlh, struct ne hdr = (trace_hdr_t *)RTA_DATA(rta); printk(KERN_INFO "Receive type:%u of message, version:%u, sequence:%u, is_reply:%u ", nlh->nlmsg_type, hdr->ver, hdr->seq, hdr->is_reply); + printk(KERN_INFO "Receive netlink-message-pid:%u ", nlh->nlmsg_pid); policy = (trace_policy_t *)(hdr + 1); printk(KERN_DEBUG "Receive policy:"); printk(KERN_DEBUG " protocol:%u", policy->protocol); diff --git a/Platform/user/trace/trace-api/trace_api.c b/Platform/user/trace/trace-api/trace_api.c index 96cd24d16..57a43b813 100755 --- a/Platform/user/trace/trace-api/trace_api.c +++ b/Platform/user/trace/trace-api/trace_api.c @@ -12,7 +12,7 @@ #include #include #include - +#include #include "libnetlinku.h" //#include "policy_client.h" @@ -36,6 +36,9 @@ #define NETLINK_GROUP_TRACE_ID 0 +#define EXEC_CR_SK_WAIT_TIMEOUT 2 + + typedef struct _cb_arg { struct hlist_node node; uint32_t seq; @@ -64,6 +67,8 @@ static uint32_t g_seq = 0; static volatile sess_t g_sess = {0}; static int g_channel_open = -1; +static sem_t g_cr_sk_sem; + static trace_ret_t get_and_del_arg_from_hlist(const uint32_t seq, cb_arg_t **out) { @@ -158,6 +163,17 @@ static int trace_recv_handle(struct pdelivnl_ctrl_data *ctrl, static void *cb_thread(void *arg) { SYSLOG_INFO("Callback thread is started"); + + g_channel_open = pdelivnl_open(NETLINK_GROUP_TRACE_ID); + if(g_channel_open < 0) + { + SYSLOG_ERR("pdelivnl_open fail:%d", g_channel_open); + return NULL; + } + + if (sem_post(&g_cr_sk_sem) != 0) { + SYSLOG_ERR("Set semaphore of g_cr_sk_sem is failure:%d", errno); + } pdelivnl_listen(NETLINK_GROUP_TRACE_ID, trace_recv_handle, NULL); @@ -174,7 +190,7 @@ static trace_ret_t cfg_channel_send(const uint32_t seq, const trace_policy_t *p hdr->nlmsg_len = NLMSG_HDRLEN; hdr->nlmsg_flags = NLM_F_REQUEST /* | NLM_F_ACK */; hdr->nlmsg_type = TRACE_CFG_POLICY_REQ; - hdr->nlmsg_pid = getpid(); + // hdr->nlmsg_pid = getpid(); trace_req_t req; req.hdr.ver = 1; @@ -184,12 +200,15 @@ static trace_ret_t cfg_channel_send(const uint32_t seq, const trace_policy_t *p commnl_addattr_l(hdr, sizeof(buf), TRACE_MSG_POLICY_REQ, &req, sizeof(trace_req_t)); SYSLOG_DEBUG("Send msg len:%u, msg_flag:%u, msg_type:%u", hdr->nlmsg_len, hdr->nlmsg_flags, hdr->nlmsg_type); + SYSLOG_DEBUG("Send netlink-message-pid:%u ", hdr->nlmsg_pid); SYSLOG_DEBUG("Send hdr: is_reply:%d, seq:%u, ver:%u", req.hdr.is_reply, req.hdr.seq, req.hdr.ver); SYSLOG_DEBUG("Send policy:"); - SYSLOG_DEBUG(" src family:%u, src ip:%02x, sport:%u", - req.policy.src.family, req.policy.src.addr.ip4.s_addr, req.policy.sport); - SYSLOG_DEBUG(" dst family:%u, dst ip:%02x, dport:%u", - req.policy.dst.family, req.policy.dst.addr.ip4.s_addr, req.policy.dport); + SYSLOG_DEBUG(" src family:%u, src ip:%02x (%s), sport:%u (host order %u)", + req.policy.src.family, req.policy.src.addr.ip4.s_addr, inet_ntoa(req.policy.src.addr.ip4), + req.policy.sport, ntohs(req.policy.sport)); + SYSLOG_DEBUG(" dst family:%u, dst ip:%02x (%s), dport:%u (host order %u)", + req.policy.dst.family, req.policy.dst.addr.ip4.s_addr, inet_ntoa(req.policy.dst.addr.ip4), + req.policy.dport, ntohs(req.policy.dport)); SYSLOG_DEBUG(" protocol:%u, app_type:%u, base_type:%u", req.policy.protocol, req.policy.app_type, req.policy.base_type); /*发送组装好的netlink消息*/ @@ -230,19 +249,43 @@ trace_ret_t trace_client_init() } //g_channel_open = commcfgnl_open(); + /* netlink通信机制决定同一个线程里不能同时启用两个pdeliv socket, + * 鉴于trace库的调用者(如DPI)可能原本已启用了一个pdeliv socket, + * 因此,将trace库里的pdeliv socket创建移至trace的子线程中 */ + #if 0 g_channel_open = pdelivnl_open(NETLINK_GROUP_TRACE_ID); if(g_channel_open < 0) { SYSLOG_ERR("pdelivnl_open fail:%d", g_channel_open); goto FAIL; } + #endif + + if (sem_init(&g_cr_sk_sem, 0, 0) != 0) { + SYSLOG_ERR("Init g_cr_sk_sem is failure:%d", errno); + goto FAIL; + } + + struct timespec timeout; + if (clock_gettime(CLOCK_REALTIME, &timeout) == -1) { + SYSLOG_ERR("Get current time is failure:%d", errno); + goto FAIL; + } + + timeout.tv_sec += EXEC_CR_SK_WAIT_TIMEOUT; int ret = pthread_create(&g_client_thread, NULL, cb_thread, NULL); if (ret != 0) { SYSLOG_ERR("Create the thread of callback is failure:%d", ret); goto FAIL; } - + + /* 如果sem 信号量值>0,则sem_timedwait 立即返回; + * 如果sem 信号量值≤0,则 sem_timedwait 阻塞等待 TIMEOUT秒后再返回。*/ + ret = sem_timedwait(&g_cr_sk_sem, &timeout); + SYSLOG_DEBUG("sem_timedwait for g_cr_sk_sem, return:%d", ret); + + sem_destroy(&g_cr_sk_sem); return TRACE_SUCCESS; FAIL: while (i > 0) { @@ -250,7 +293,8 @@ FAIL: pthread_mutex_destroy((pthread_mutex_t *)&g_sess.hsess_mutex[i]); } cfg_channel_close(); - + + sem_destroy(&g_cr_sk_sem); return TRACE_FAILURE; }