From 001782b58655e3a75b00f4db57250db319d525ff Mon Sep 17 00:00:00 2001 From: kejun.gao Date: Mon, 31 Oct 2011 11:42:49 +0000 Subject: Add timeout-retransmision between C/S based PF_UNIX --- diff --git a/jni/src/pppoe_ctrl.c b/jni/src/pppoe_ctrl.c index a1ef844..fcac231 100755 --- a/jni/src/pppoe_ctrl.c +++ b/jni/src/pppoe_ctrl.c @@ -12,16 +12,17 @@ #include #include +#include #include #include "pppoe_ctrl.h" #define LOCAL_TAG "PPPOE_CTRL" +#define TMPDIR "/etc/ppp" struct pppoe_ctrl * pppoe_ctrl_open(const char *ctrl_path) { struct pppoe_ctrl *ctrl; - static int counter = 0; int ret; size_t res; int tries = 0; @@ -40,10 +41,10 @@ struct pppoe_ctrl * pppoe_ctrl_open(const char *ctrl_path) __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s(ctrl->s = %d)\n", __FUNCTION__, ctrl->s); ctrl->local.sun_family = AF_UNIX; - counter++; + try_again: ret = snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), - "/dev/socket/ppp_cli-%d", getpid()); + "%s/ppp_cli-%d", TMPDIR, getpid()); __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s: ctrl->local.sun_path: %s\n", __FUNCTION__, ctrl->local.sun_path); if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) { @@ -54,7 +55,7 @@ try_again: tries++; if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, sizeof(ctrl->local)) < 0) { -#if 0 +#if 1 if (errno == EADDRINUSE && tries < 2) { /* * getpid() returns unique identifier for this instance @@ -63,6 +64,7 @@ try_again: * Remove the file and try again. */ unlink(ctrl->local.sun_path); + __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"%s: bind failed(%s)\n", __FUNCTION__, strerror(errno)); goto try_again; } @@ -107,17 +109,74 @@ void pppoe_ctrl_close(struct pppoe_ctrl *ctrl) free(ctrl); } +#define REQUEST_BUF_LEN 1024 +#define ACK_BUF_LEN 128 +#define RESEND_CNT_MAX 10 + +static char request_buf[REQUEST_BUF_LEN]; +static char ack_buf[ACK_BUF_LEN]; +static int req_no = 0; int pppoe_ctrl_request(struct pppoe_ctrl *ctrl, const char *cmd, size_t cmd_len) -{ - if (send(ctrl->s, cmd, cmd_len, 0) < 0) { - __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"send command[%s] failed\n", cmd); - return -1; - } +{ + int nwritten = -1; + int acked = 0; + fd_set rfds; + struct timeval tv; + int res; + int pid_and_reqno_len =0; + int resend_cnt = 0; + + do { + request_buf[0] = 0; + nwritten = sprintf(request_buf, "%d\t", getpid()); + nwritten += sprintf(request_buf + nwritten, "%d\t", req_no++); + pid_and_reqno_len = nwritten; + nwritten += sprintf(request_buf + nwritten, "%s", cmd); + + if (send(ctrl->s, request_buf, nwritten, 0) < 0) { + __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"send command[%s] failed(%s)\n", cmd, strerror(errno)); + goto exit_func; + } + + resend_cnt++; + + tv.tv_sec = 10; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_SET(ctrl->s, &rfds); + res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv); + if ( res < 0 ) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"failed to select(%s)\n", strerror(errno)); + goto exit_func; + } else if ( 0 == res ){ + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"Timeout to recv ack, resend request\n"); + continue; + }else if (FD_ISSET(ctrl->s, &rfds)) { + res = recv(ctrl->s, ack_buf, ACK_BUF_LEN-1, 0); + if (res < 0) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"failed to recv ack(%s)\n", strerror(errno)); + goto exit_func; + } + + if (0 == strncmp(ack_buf, request_buf,pid_and_reqno_len)) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"recved VALID ack\n"); + acked = 1; + } + else { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"recved INVALID ack: pid_and_reqno_len(%d)\n", pid_and_reqno_len); + ack_buf[pid_and_reqno_len] = 0; + request_buf[pid_and_reqno_len] = 0; + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"ack_buf[%s]\n", ack_buf); + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"request_buf[%s]\n", request_buf); + } + } + }while(!acked && resend_cnt < RESEND_CNT_MAX); - __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"send command[%s] OK\n", cmd); - return 0; +exit_func: + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"send command[%s] %s\n", cmd, acked ? "OK" : "failed"); + return acked ? 0 : -1; } diff --git a/jni/src/pppoe_wrapper.c b/jni/src/pppoe_wrapper.c index 8cf721f..30af15d 100755 --- a/jni/src/pppoe_wrapper.c +++ b/jni/src/pppoe_wrapper.c @@ -111,8 +111,8 @@ static int ppp_stop() int main(int argc, char * argv[]) { int socket_fd; - struct sockaddr_un name; - int i, len; + struct sockaddr_un cli_addr, serv_addr; + int i, len, clilen = 0; int ppp_cmd_len; socket_fd = socket(PF_UNIX, SOCK_DGRAM, 0); @@ -122,15 +122,15 @@ int main(int argc, char * argv[]) exit(-1); } - memset(&name,0,sizeof(name)); + memset(&serv_addr,0,sizeof(serv_addr)); __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, "create AF_UNIX socket:%d OK\n",socket_fd); unlink("/dev/socket/pppd"); - name.sun_family = AF_UNIX; - strncpy(name.sun_path, "/dev/socket/pppd", sizeof(name.sun_path) - 1); + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, "/dev/socket/pppd", sizeof(serv_addr.sun_path) - 1); - if (bind(socket_fd, (struct sockaddr *)&name, sizeof(struct sockaddr_un)) < 0) { + if (bind(socket_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_un)) < 0) { __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "failed to bind socket(%s)\n", strerror(errno)); exit(-1); @@ -140,6 +140,7 @@ int main(int argc, char * argv[]) struct timeval tv; int res; fd_set rfds; + char *cmd; for (;;) { tv.tv_sec = 10; @@ -147,19 +148,55 @@ int main(int argc, char * argv[]) FD_ZERO(&rfds); FD_SET(socket_fd, &rfds); res = select(socket_fd + 1, &rfds, NULL, NULL, &tv); - if (FD_ISSET(socket_fd, &rfds)) { - res = recv(socket_fd, ppp_cmd, PPP_CMD_LEN_MAX-1, 0); - if (res < 0) + if (res > 0 && FD_ISSET(socket_fd, &rfds)) { + clilen = sizeof (struct sockaddr_un); + res = recvfrom(socket_fd, ppp_cmd, PPP_CMD_LEN_MAX-1, 0, + (struct sockaddr *)&cli_addr,&clilen); + if (res < 0) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, + "FAILED TO RECVFROM\n"); + return res; + } + + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, + "client: [%s][%d]\n", + cli_addr.sun_path, clilen); + ppp_cmd[res] = '\0'; ppp_cmd_len = res; + + cmd = strchr(ppp_cmd, '\t'); + if (!cmd) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, + "recv invalid cmd(No TAB found): [%s]\n",ppp_cmd); + continue; + } + cmd++; + + cmd = strchr(cmd, '\t'); + if (!cmd) { + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, + "recv invalid cmd(Second TAB NOT found): [%s]\n",ppp_cmd); + continue; + } + cmd++; + + if (sendto(socket_fd, ppp_cmd, cmd - ppp_cmd, 0, + (struct sockaddr *)&cli_addr, clilen) < 0) { + __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"failed to send ACK(%s)\n", strerror(errno)); + continue; + } + __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, - "recv cmd: [%s]\n",ppp_cmd); - if ( 0 == strcmp(ppp_cmd, "ppp-stop") ) { + "recv cmd: [%s]\n",cmd); + + + if ( 0 == strcmp(cmd, "ppp-stop") ) { ppp_stop(); } else { - system(ppp_cmd); + system(cmd); } } } -- cgit