summaryrefslogtreecommitdiff
authorkejun.gao <kejun.gao@amlogic.com>2011-10-31 11:42:49 (GMT)
committer kejun.gao <kejun.gao@amlogic.com>2011-10-31 11:42:49 (GMT)
commit001782b58655e3a75b00f4db57250db319d525ff (patch)
tree55437ff85d3edc71c858e5b2347dbca68f12ac07
parent0ed76b207cb0edaaac8e835dd5e507448e2cf71e (diff)
downloadpppoe-001782b58655e3a75b00f4db57250db319d525ff.zip
pppoe-001782b58655e3a75b00f4db57250db319d525ff.tar.gz
pppoe-001782b58655e3a75b00f4db57250db319d525ff.tar.bz2
Add timeout-retransmision between C/S based PF_UNIX
Diffstat
-rwxr-xr-xjni/src/pppoe_ctrl.c81
-rwxr-xr-xjni/src/pppoe_wrapper.c61
2 files changed, 119 insertions, 23 deletions
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 <netinet/in.h>
#include <sys/un.h>
+#include <sys/stat.h>
#include <android/log.h>
#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);
}
}
}