20180912_jeffrey - silenceuncrio/diary GitHub Wiki

1300

看到 daemon_restart()

static void daemon_restart(DAEMON_CTRL_T *dmn_ctrl)
{
    sWebConfig	  *cfg=&gWebCtrl.cfg;
    WEB_INFO("[DID%d] remain IP server retry for %d times.\n",dmn_ctrl->did,dmn_ctrl->retry_cnt);
    //Daemon shutdown
    if(DAEMON_STATUS_OFF!=dmn_ctrl->status)
    {
        if(DAEMON_STATUS_RUNNING==dmn_ctrl->status &&
                BAD_PID!=dmn_ctrl->pid)
        {
            WEB_INFO("[DMN] killed (%d).\n",dmn_ctrl->pid);
            ICOS_kill(dmn_ctrl->pid);
        }
        dmn_ctrl->status=DAEMON_STATUS_WAIT_EXIT;
        WEB_INFO("[DMN] Wait exit(%d).\n",dmn_ctrl->pid);
        return;
    }



    if (DID_HTTPS == dmn_ctrl->did &&
            (ATTVAL_WEBMODE_HTTPS == cfg->mode || ATTVAL_WEBMODE_BOTH == cfg->mode)
       )
    {
        gen_key_files();
    }



    dmn_ctrl->pid=BAD_PID;
    dmn_ctrl->status=DAEMON_STATUS_OFF;
    //Daemon start
    if(ICOS_SUCCESS==is_request_start(dmn_ctrl))
    {
        char argv[256]= {0};

        if (DID_HTTPS == dmn_ctrl->did)
        {
            snprintf(argv,sizeof(argv)," -p %d -d %s -s", cfg->httpsPort, WEB_DAEMON_HTML_DIR);
        }
        else
        {
            snprintf(argv,sizeof(argv)," -p %d -d %s", cfg->httpdPort, WEB_DAEMON_HTML_DIR);
        }

        WEB_DBG("[DMN]Lanch=>%s %s\n",WEB_DAEMON_BIN_FILE,argv);
        dmn_ctrl->pid=ICOS_ProcLaunch(MODULE_WEB,WEB_DAEMON_BIN_FILE,argv,NULL);

        if (dmn_ctrl->pid == BAD_PID)
        {
            dmn_ctrl->status = DAEMON_STATUS_OFF;
            // use next NotifyHandler to invoke daemon_restart() again
            WEB_DBG("use next NotifyHandler to invoke daemon_restart() again\n");
            ICOS_msg_sendto(MODULE_WEB, MODULE_WEB, NULL, 0, ICOS_UCAST_DMN_RESTART);
        }
        else
        {
            dmn_ctrl->status = DAEMON_STATUS_RUNNING;
        }
    }
}

daemon_restart(DAEMON_CTRL_T *dmn_ctrl) 要處理的不是 gWebCtrl.dmn_ctrl[0] 就是 gWebCtrl.dmn_ctrl[0]

名稱叫 restart 就算你現在在 running 也先 kill 掉再說

 //Daemon shutdown
    if(DAEMON_STATUS_OFF!=dmn_ctrl->status)
    {
        if(DAEMON_STATUS_RUNNING==dmn_ctrl->status &&
                BAD_PID!=dmn_ctrl->pid)
        {
            WEB_INFO("[DMN] killed (%d).\n",dmn_ctrl->pid);
            ICOS_kill(dmn_ctrl->pid);
        }
        dmn_ctrl->status=DAEMON_STATUS_WAIT_EXIT;
        WEB_INFO("[DMN] Wait exit(%d).\n",dmn_ctrl->pid);
        return;
    }

如果是 HTTPS 這個 daemon 的話 還要呼叫 gen_key_files()

    if (DID_HTTPS == dmn_ctrl->did &&
            (ATTVAL_WEBMODE_HTTPS == cfg->mode || ATTVAL_WEBMODE_BOTH == cfg->mode)
       )
    {
        gen_key_files();
    }

再來的部分由 is_request_start() 來判斷該 dmn_ctrl 需不需要 restart

    dmn_ctrl->pid=BAD_PID;
    dmn_ctrl->status=DAEMON_STATUS_OFF;
    //Daemon start
    if(ICOS_SUCCESS==is_request_start(dmn_ctrl))
    {
        ...
    }

1330

看一下 is_request_start()

static int is_request_start(DAEMON_CTRL_T *dmn_ctrl)
{
    sWebConfig	  *cfg=&gWebCtrl.cfg;
    RT_INFO_T	  *rt_info=&gWebCtrl.rt_info;

    //Config check
    if(!((DID_HTTPD==dmn_ctrl->did && (ATTVAL_WEBMODE_HTTPD==cfg->mode || ATTVAL_WEBMODE_BOTH==cfg->mode)) ||
            (DID_HTTPS==dmn_ctrl->did && (ATTVAL_WEBMODE_HTTPS==cfg->mode || ATTVAL_WEBMODE_BOTH==cfg->mode))))
    {
        //WEB_INFO("[CFG]off mode.\n");
        web_dump(DUMP_CFG|DUMP_DMN,"cfg not allowed");
        return ICOS_FAILURE;
    }
    //Daemon control
    if(0==dmn_ctrl->active)
    {
        WEB_INFO("[DMN]disabled.\n");
        web_dump(DUMP_DMN,NULL);
        return ICOS_FAILURE;
    }

    if (DID_HTTPS == dmn_ctrl->did && 0 == dmn_ctrl->is_keyfile_ready )
    {
        WEB_INFO("[DMN]disabled cause key not ready.\n");
        web_dump(DUMP_DMN,NULL);
        return ICOS_FAILURE;
    }



    if(ICOS_FAILURE==create_daemon_conf(dmn_ctrl))
    {
        WEB_INFO("[DMN]Fail to gen DID%d config.\n",dmn_ctrl->did);
        return ICOS_FAILURE;
    }
    return ICOS_SUCCESS;
}

由 did 區分是 HTTPD 或是 HTTPD 再搭配 cfg->mode 來決定該 dmn_ctrl 是否需要 start

    //Config check
    if(!((DID_HTTPD==dmn_ctrl->did && (ATTVAL_WEBMODE_HTTPD==cfg->mode || ATTVAL_WEBMODE_BOTH==cfg->mode)) ||
            (DID_HTTPS==dmn_ctrl->did && (ATTVAL_WEBMODE_HTTPS==cfg->mode || ATTVAL_WEBMODE_BOTH==cfg->mode))))
    {
        //WEB_INFO("[CFG]off mode.\n");
        web_dump(DUMP_CFG|DUMP_DMN,"cfg not allowed");
        return ICOS_FAILURE;
    }

再來的 daemon control 會依據該 dmn_ctrl 本身的 active 值來決定要不要 restart(start)

    //Daemon control
    if(0==dmn_ctrl->active)
    {
        WEB_INFO("[DMN]disabled.\n");
        web_dump(DUMP_DMN,NULL);
        return ICOS_FAILURE;
    }

不過從頭到尾就只有 web_init() 把兩個 dmn_ctrl 的 active 設為 1

static int web_init(sWebConfig *cfgp)
{
    //Daemon
    for(i=0; MAX_DAEMON_NUM>i; i++)
    {
        ...
        gWebCtrl.dmn_ctrl[i].active=1;
        ...
    }
}

再來是 HTTPS daemon 專屬

    if (DID_HTTPS == dmn_ctrl->did && 0 == dmn_ctrl->is_keyfile_ready )
    {
        WEB_INFO("[DMN]disabled cause key not ready.\n");
        web_dump(DUMP_DMN,NULL);
        return ICOS_FAILURE;
    }

如果 dmn_ctrl 本身的 is_keyfile_ready 值為 0 的話 就不 restart

再來是準備 daemon 運作時需要的 configuration

    if(ICOS_FAILURE==create_daemon_conf(dmn_ctrl))
    {
        WEB_INFO("[DMN]Fail to gen DID%d config.\n",dmn_ctrl->did);
        return ICOS_FAILURE;
    }

這一部分的 code 應該是不需要的

1335

回到 daemon_restart()

假設 is_request_start() 回答是需要 restart 的

        char argv[256]= {0};

        if (DID_HTTPS == dmn_ctrl->did)
        {
            snprintf(argv,sizeof(argv)," -p %d -d %s -s", cfg->httpsPort, WEB_DAEMON_HTML_DIR);
        }
        else
        {
            snprintf(argv,sizeof(argv)," -p %d -d %s", cfg->httpdPort, WEB_DAEMON_HTML_DIR);
        }

        WEB_DBG("[DMN]Lanch=>%s %s\n",WEB_DAEMON_BIN_FILE,argv);
        dmn_ctrl->pid=ICOS_ProcLaunch(MODULE_WEB,WEB_DAEMON_BIN_FILE,argv,NULL);

        if (dmn_ctrl->pid == BAD_PID)
        {
            dmn_ctrl->status = DAEMON_STATUS_OFF;
            // use next NotifyHandler to invoke daemon_restart() again
            WEB_DBG("use next NotifyHandler to invoke daemon_restart() again\n");
            ICOS_msg_sendto(MODULE_WEB, MODULE_WEB, NULL, 0, ICOS_UCAST_DMN_RESTART);
        }
        else
        {
            dmn_ctrl->status = DAEMON_STATUS_RUNNING;
        }

由 did 決定是 HTTPD 或是 HTTPS

然後準備相對應的參數再透過 ICOS_ProcLaunch 執行該 process

並把回傳值用 pid keep 起來

        if (dmn_ctrl->pid == BAD_PID)
        {
            dmn_ctrl->status = DAEMON_STATUS_OFF;
            // use next NotifyHandler to invoke daemon_restart() again
            WEB_DBG("use next NotifyHandler to invoke daemon_restart() again\n");
            ICOS_msg_sendto(MODULE_WEB, MODULE_WEB, NULL, 0, ICOS_UCAST_DMN_RESTART);
        }
        else
        {
            dmn_ctrl->status = DAEMON_STATUS_RUNNING;
        }

如果 ICOS_ProcLaunch 失敗了就利用 ICOS_msg_sendto(MODULE_WEB, MODULE_WEB, NULL, 0, ICOS_UCAST_DMN_RESTART)

這樣一來下一次的 notify_web() 便會利用 flag = FLAG_DMN_RESTART 再觸發 daemon_restart()

    switch(pevent->event_id)
    {
        case ICOS_SYSTEM_UPDATE:
        case ICOS_UCAST_DMN_RESTART:
            WEB_INFO("daemon restart\n");
            web_dump(DUMP_ALL,"init config");
            for(i=0; MAX_DAEMON_NUM>i; i++)
            {
                gWebCtrl.dmn_ctrl[i].flag = FLAG_DMN_RESTART;
            }
            break;

        default:
            break;
    }

1350

回到 log

再來是

1536650412[20180911 7:20:12] [msgcb_web:1209]IN(DID0,pid 2195)
<--
failed to load the session from binary
Icos_users.session_ttl: 300 sec
Icos_users.users[0].name: root
Icos_users.users[0].pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Icos_users.users[0].level: 3
Icos_users.users[1].name:
Icos_users.users[1].pass:
Icos_users.users[1].level: 0
Icos_users.users[2].name:
Icos_users.users[2].pass:
Icos_users.users[2].level: 0
Icos_users.users[3].name:
Icos_users.users[3].pass:
Icos_users.users[3].level: 0
Starting iweb on port 80, serving /www
-->

這要先看到 msgcb_web()

static int msgcb_web(char *msg, pid_t pid, int rc)
{
    int i;
    DAEMON_CTRL_T *dmn_ctrl=NULL;

    for(i=0; MAX_DAEMON_NUM>i; i++)
    {
        if(pid==gWebCtrl.dmn_ctrl[i].pid)
        {
            WEB_INFO("IN(DID%d,pid %d)\n",gWebCtrl.dmn_ctrl[i].did,gWebCtrl.dmn_ctrl[i].pid);
            dmn_ctrl=&gWebCtrl.dmn_ctrl[i];
            break;
        }
    }
    if(NULL==dmn_ctrl)
    {
        return ICOS_SUCCESS;
    }

    if(msg)
    {
#if 1 //debug
        WEB_DAEMON("<--\n");
        WEB_DAEMON("%s",msg);
        WEB_DAEMON("-->\n");
#endif
        //daemon_event(dmn_ctrl,msg);
    }
    return ICOS_SUCCESS;
}

1536650412[20180911 7:20:12] [msgcb_web:1209]IN(DID0,pid 2195) 得知

DID0 這個剛剛透過 ICOS_ProcLaunch 執行的 process 有 output 了

snprintf(argv,sizeof(argv)," -p %d -d %s", cfg->httpdPort, WEB_DAEMON_HTML_DIR);
dmn_ctrl->pid=ICOS_ProcLaunch(MODULE_WEB,WEB_DAEMON_BIN_FILE,argv,NULL);

output - msg 如下

failed to load the session from binary
Icos_users.session_ttl: 300 sec
Icos_users.users[0].name: root
Icos_users.users[0].pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Icos_users.users[0].level: 3
Icos_users.users[1].name:
Icos_users.users[1].pass:
Icos_users.users[1].level: 0
Icos_users.users[2].name:
Icos_users.users[2].pass:
Icos_users.users[2].level: 0
Icos_users.users[3].name:
Icos_users.users[3].pass:
Icos_users.users[3].level: 0
Starting iweb on port 80, serving /www

1400

再來是自己不感興趣的 broadcast event

1536650413[20180911 7:20:13] [notify_web:862]IN(E48|S41|D00)
1536650413[20180911 7:20:13] [notify_web:862]IN(E50|S59|D00)
1536650422[20180911 7:20:22] [notify_web:862]IN(E59|S59|D00)
1536650427[20180911 7:20:27] [notify_web:862]IN(E02|S56|D00)
1536650427[20180911 7:20:27] [notify_web:862]IN(E01|S56|D00)
1536650428[20180911 7:20:28] [notify_web:862]IN(E40|S35|D00)
1536650432[20180911 7:20:32] [notify_web:862]IN(E46|S35|D00)
1536650432[20180911 7:20:32] [notify_web:862]IN(E46|S35|D00)
1536650432[20180911 7:20:32] [notify_web:862]IN(E47|S35|D00)
1536650432[20180911 7:20:32] [notify_web:862]IN(E50|S59|D00)
1536650440[20180911 7:20:40] [notify_web:862]IN(E59|S59|D00)

1405

再來是重頭戲了

1536650446[20180911 7:20:46] [termcb_web:1121]HTTPS key and cert generated done.
1536650446[20180911 7:20:46] [web_dump:516]===Key file generated done, daemon restart===
1536650446[20180911 7:20:46] [web_dump:562][DMN0]active=1,pid=2195,status=1,flag=0x0,DID0
1536650446[20180911 7:20:46] [web_dump:562][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1536650446[20180911 7:20:46] [daemon_restart:706][DID1] remain IP server retry for 6 times.
1536650446[20180911 7:20:46] [gen_key_files:578]IN
1536650446[20180911 7:20:46] [gen_key_files:593]OUT
1536650446[20180911 7:20:46] [create_daemon_conf:605]IN
1536650446[20180911 7:20:46] [create_daemon_conf:616]cmd_buf=>dir=/
1536650446[20180911 7:20:46] [create_daemon_conf:621]cmd_buf=>cgipat=cgi-bin/**
1536650446[20180911 7:20:46] [create_daemon_conf:626]cmd_buf=>chroot
1536650446[20180911 7:20:46] [create_daemon_conf:631]cmd_buf=>user=root
1536650446[20180911 7:20:46] [create_daemon_conf:636]cmd_buf=>max_age=0
1536650446[20180911 7:20:46] [create_daemon_conf:641]cmd_buf=>debug
1536650446[20180911 7:20:46] [create_daemon_conf:648]cmd_buf=>ssl
1536650446[20180911 7:20:46] [create_daemon_conf:653]cmd_buf=>certfile=/etc/icos/ca/cert.pem
1536650446[20180911 7:20:46] [daemon_restart:748][DMN]Lanch=>/usr/sbin/iweb  -p 443 -d /www -s

解析這些 log 之前先看到昨天還沒解析的 daemon_restart(&gWebCtrl.dmn_ctrl[1]) 的 log

1536650409[20180911 7:20:9] [gen_key_files:578]IN
1536650409[20180911 7:20:9] [gen_key_files:590]iweb genkey pid = 2198
1536650409[20180911 7:20:9] [gen_key_files:593]OUT

看到 gen_key_files()

static void gen_key_files(void)
{
    int pid;
    char cmd[256];

    WEB_INFO("IN\n");
    if (-1 == access(WEB_DAEMON_KEY_FILE, F_OK))
    {
#if 0
        snprintf(cmd, sizeof(cmd),
                 "req -x509 -newkey rsa:1024 -keyout %s -out %s -days 365 -nodes -subj '/CN=localhost'",
                 WEB_DAEMON_KEY_FILE, WEB_DAEMON_CERT_FILE);
        pid = ICOS_ProcLaunch(MODULE_WEB, WEB_DAEMON_KEYGEN_FILE, cmd, NULL);
        WEB_INFO("iweb genkey cmd = %s\n", cmd);
        WEB_INFO("iweb genkey pid = %d\n", pid);
#else
        pid = ICOS_ProcLaunch(MODULE_WEB, "web_x509.sh", NULL, NULL);
        WEB_INFO("iweb genkey pid = %d\n", pid);
#endif
    }
    WEB_INFO("OUT\n");
}

這邊是依據 WEB_DAEMON_KEY_FILE 的存在與否來判斷是否需要產生 key

    if (-1 == access(WEB_DAEMON_KEY_FILE, F_OK))
    {
        ...
    }

產生 key 是利用 ICOS_ProcLaunch(MODULE_WEB, "web_x509.sh", NULL, NULL)

這樣 web_x509.sh 執行結束後會觸發 termcb_web()

    for (i = 0; MAX_DAEMON_NUM > i; i ++)
    {
        if ( DID_HTTPS == gWebCtrl.dmn_ctrl[i].did && 0 == gWebCtrl.dmn_ctrl[i].is_keyfile_ready )
        {
            int keyfile  = (0 == access(WEB_DAEMON_KEY_FILE, F_OK));
            int certfile = (0 == access(WEB_DAEMON_CERT_FILE, F_OK));

            if (keyfile && certfile)
            {
                char cmd[256]= {0};
                WEB_INFO("HTTPS key and cert generated done.\n");
                ICOS_slog(MODULE_WEB, LOG_INFO, "iweb HTTPS key and cert generated.");
                gWebCtrl.dmn_ctrl[i].is_keyfile_ready = 1;

                gWebCtrl.dmn_ctrl[i].status = DAEMON_STATUS_OFF;
                gWebCtrl.dmn_ctrl[i].pid = BAD_PID;
                web_dump(DUMP_DMN, "Key file generated done, daemon restart");
                daemon_restart(&gWebCtrl.dmn_ctrl[i]);
            }
            else
            {
                WEB_INFO("HTTPS key and cert generated fail.\n");
            }
        }
    }

當 HTTPS 這 dmn_ctrl 的 is_keyfile_ready 還沒 ready 的時候

        if ( DID_HTTPS == gWebCtrl.dmn_ctrl[i].did && 0 == gWebCtrl.dmn_ctrl[i].is_keyfile_ready )
        {
         ...
        }

如果 keyfile 和 certfile 都準備好了

            int keyfile  = (0 == access(WEB_DAEMON_KEY_FILE, F_OK));
            int certfile = (0 == access(WEB_DAEMON_CERT_FILE, F_OK));

            if (keyfile && certfile)
            {
                char cmd[256]= {0};
                WEB_INFO("HTTPS key and cert generated done.\n");
                ICOS_slog(MODULE_WEB, LOG_INFO, "iweb HTTPS key and cert generated.");
                gWebCtrl.dmn_ctrl[i].is_keyfile_ready = 1;

                gWebCtrl.dmn_ctrl[i].status = DAEMON_STATUS_OFF;
                gWebCtrl.dmn_ctrl[i].pid = BAD_PID;
                web_dump(DUMP_DMN, "Key file generated done, daemon restart");
                daemon_restart(&gWebCtrl.dmn_ctrl[i]);
            }
            else
            {
                WEB_INFO("HTTPS key and cert generated fail.\n");
            }

便修改 is_keyfile_ready 為 1 再次觸發 daemon_restart(&gWebCtrl.dmn_ctrl[1])

                gWebCtrl.dmn_ctrl[i].is_keyfile_ready = 1;
                daemon_restart(&gWebCtrl.dmn_ctrl[i]);

這便產生了 log

1536650446[20180911 7:20:46] [termcb_web:1121]HTTPS key and cert generated done.
1536650446[20180911 7:20:46] [web_dump:516]===Key file generated done, daemon restart===
1536650446[20180911 7:20:46] [web_dump:562][DMN0]active=1,pid=2195,status=1,flag=0x0,DID0
1536650446[20180911 7:20:46] [web_dump:562][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1

那這一次 WebCtrl.dmn_ctrl[1] 的 daemon_restart() 因為 is_keyfile_ready 為 1

所以這次的 is_request_start() 就 PASS 了 is_keyfile_ready 的檢查

    if (DID_HTTPS == dmn_ctrl->did && 0 == dmn_ctrl->is_keyfile_ready )
    {
        WEB_INFO("[DMN]disabled cause key not ready.\n");
        web_dump(DUMP_DMN,NULL);
        return ICOS_FAILURE;
    }

所以 daemon_restart() 會去作下面這些

        snprintf(argv,sizeof(argv)," -p %d -d %s -s", cfg->httpsPort, WEB_DAEMON_HTML_DIR);
        WEB_DBG("[DMN]Lanch=>%s %s\n",WEB_DAEMON_BIN_FILE,argv);
        dmn_ctrl->pid=ICOS_ProcLaunch(MODULE_WEB,WEB_DAEMON_BIN_FILE,argv,NULL);

也就產生了下面這些 log

1536650446[20180911 7:20:46] [daemon_restart:706][DID1] remain IP server retry for 6 times.
1536650446[20180911 7:20:46] [gen_key_files:578]IN
1536650446[20180911 7:20:46] [gen_key_files:593]OUT
1536650446[20180911 7:20:46] [create_daemon_conf:605]IN
1536650446[20180911 7:20:46] [create_daemon_conf:616]cmd_buf=>dir=/
1536650446[20180911 7:20:46] [create_daemon_conf:621]cmd_buf=>cgipat=cgi-bin/**
1536650446[20180911 7:20:46] [create_daemon_conf:626]cmd_buf=>chroot
1536650446[20180911 7:20:46] [create_daemon_conf:631]cmd_buf=>user=root
1536650446[20180911 7:20:46] [create_daemon_conf:636]cmd_buf=>max_age=0
1536650446[20180911 7:20:46] [create_daemon_conf:641]cmd_buf=>debug
1536650446[20180911 7:20:46] [create_daemon_conf:648]cmd_buf=>ssl
1536650446[20180911 7:20:46] [create_daemon_conf:653]cmd_buf=>certfile=/etc/icos/ca/cert.pem
1536650446[20180911 7:20:46] [daemon_restart:748][DMN]Lanch=>/usr/sbin/iweb  -p 443 -d /www -s

1425

後續這些 msgcb_web() 便是 HTTPS process 的 output 囉

1536650447[20180911 7:20:47] [msgcb_web:1209]IN(DID1,pid 4176)
<--
failed to load the session from binary
-->
1536650447[20180911 7:20:47] [msgcb_web:1209]IN(DID1,pid 4176)
<--
Icos_users.session_ttl: 300 sec
-->
1536650447[20180911 7:20:47] [msgcb_web:1209]IN(DID1,pid 4176)
<--
Icos_users.users[0].name: root
Icos_users.users[0].pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Icos_users.users[0].level: 3
Icos_users.users[1].name:
Icos_users.users[1].pass:
Icos_users.users[1].level: 0
Icos_users.users[2].name:
Icos_users.users[2].pass:
Icos_users.users[2].level: 0
Icos_users.users[3].name:
Icos_users.users[3].pass:
Icos_users.users[3].level: 0
Starting SSL iweb on port 443, cert from /etc/icos/web/iweb_cert.pem, key from /etc/icos/web/iweb_key.pem, serving /www
-->

1440

感覺要解 issue - 236 - (Hytec) Add checking for encrypt file to avoid https start failure. 的話

termcb_web 下手會是一個很簡潔的方式

反正 HTTP 與 HTTPS 目前都具有重啟的機制

static int termcb_web(char *msg, pid_t pid)
{
    int i;

    WEB_INFO("IN(%d)\n",pid);
    for(i=0; MAX_DAEMON_NUM>i; i++)
    {
        if(pid==gWebCtrl.dmn_ctrl[i].pid && DAEMON_STATUS_OFF!=gWebCtrl.dmn_ctrl[i].status)
        {
            gWebCtrl.dmn_ctrl[i].status=DAEMON_STATUS_OFF;
            gWebCtrl.dmn_ctrl[i].pid=BAD_PID;

#if 0
            if(0<(--gWebCtrl.dmn_ctrl[i].retry_cnt))
            {
                daemon_restart(&gWebCtrl.dmn_ctrl[i]);
                web_dump(DUMP_DMN,"Daemon killed restart");
            }
            else
            {
                WEB_INFO("###[DID%d]Daemon stopped due to reach max retry(%d).###\n",gWebCtrl.dmn_ctrl[i].did,MAX_DAEMON_RETRY_NUM);
            }
#else // do not care the max retry
            daemon_restart(&gWebCtrl.dmn_ctrl[i]);
            web_dump(DUMP_DMN,"Daemon killed restart");
#endif


        }
    }

我只要抓到目前需要重啟的是 HTTPS 的話

在呼叫 daemon_restart 之前把 key 和 cert 刪掉即可

@@ -1098,6 +1098,15 @@ static int termcb_web(char *msg, pid_t pid)
                 WEB_INFO("###[DID%d]Daemon stopped due to reach max retry(%d).###\n",gWebCtrl.dmn_ctrl[i].did,MAX_DAEMON_RETRY_NUM);
             }
 #else // do not care the max retry
+
+            if (gWebCtrl.dmn_ctrl[i].did == DID_HTTPS)
+            {
+                remove(WEB_DAEMON_KEY_FILE);
+                remove(WEB_DAEMON_CERT_FILE);
+                gWebCtrl.dmn_ctrl[i].is_keyfile_ready = 0;
+                WEB_INFO("HTTPS terminate, remove key and cert and restart the daemon\n");
+            }
+
             daemon_restart(&gWebCtrl.dmn_ctrl[i]);
             web_dump(DUMP_DMN,"Daemon killed restart");
 #endif

只 build icos

user@be6d814a16da:~/proscend/prosrc/icos$ make

libicos.so 複製到 ~/build_small/images 方便後續 tftp 的使用

user@be6d814a16da:~/proscend/prosrc/icos$ cp libicos.so ~/build_small/images

device 在更換 libicos.so 之前要把幾個正在使用該 library 的 process 先停掉

killall icoswdog
killall icospromsg
icosconfig shutdown

然後透過 tftp 下載新產出的 libicos.so

root@HWL-2501-DS:~# cd /usr/lib/
root@HWL-2501-DS:/usr/lib# ls libic*
libicos.so
root@HWL-2501-DS:/usr/lib# tftp -g -r libicos.so 192.168.1.113

故意讓 key 失效

root@HWL-2501-DS:/usr/lib# echo xxx > /etc/icos/web/iweb_
iweb_cert.pem  iweb_key.pem
root@HWL-2501-DS:/usr/lib# echo xxx > /etc/icos/web/iweb_key.pem
root@HWL-2501-DS:/usr/lib# cat /etc/icos/web/iweb_key.pem
xxx

重開機 然後觀察 web 的 log 看看失效的 key 造成什麼影響

1536734453[20180912 6:40:53] [termcb_web:1107]HTTPS terminate, remove key and cert and restart the daemon
1536734453[20180912 6:40:53] [daemon_restart:706][DID1] remain IP server retry for 6 times.
1536734453[20180912 6:40:53] [gen_key_files:578]IN
1536734453[20180912 6:40:53] [gen_key_files:590]iweb genkey pid = 1814
1536734453[20180912 6:40:53] [gen_key_files:593]OUT
1536734453[20180912 6:40:53] [is_request_start:688][DMN]disabled cause key not ready.
1536734453[20180912 6:40:53] [web_dump:562][DMN0]active=1,pid=1669,status=1,flag=0x0,DID0
1536734453[20180912 6:40:53] [web_dump:562][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1536734453[20180912 6:40:53] [web_dump:516]===Daemon killed restart===
1536734453[20180912 6:40:53] [web_dump:562][DMN0]active=1,pid=1669,status=1,flag=0x0,DID0
1536734453[20180912 6:40:53] [web_dump:562][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1536734453[20180912 6:40:53] [termcb_web:1141]HTTPS key and cert generated fail.
1536734453[20180912 6:40:53] [msgcb_web:1218]IN(DID0,pid 1669)
<--
failed to load the session from binary
Icos_users.session_ttl: 300 sec
Icos_users.users[0].name: root
Icos_users.users[0].pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Icos_users.users[0].level: 3
Icos_users.users[1].name:
Icos_users.users[1].pass:
Icos_users.users[1].level: 0
Icos_users.users[2].name:
Icos_users.users[2].pass:
Icos_users.users[2].level: 0
Icos_users.users[3].name:
Icos_users.users[3].pass:
Icos_users.users[3].level: 0
Starting iweb on port 80, serving /www
-->
1536734454[20180912 6:40:54] [notify_web:862]IN(E48|S41|D00)
1536734454[20180912 6:40:54] [notify_web:862]IN(E50|S59|D00)
1536734460[20180912 6:41:0] [termcb_web:1082]IN(1814)
1536734460[20180912 6:41:0] [termcb_web:1130]HTTPS key and cert generated done.
1536734460[20180912 6:41:0] [web_dump:516]===Key file generated done, daemon restart===
1536734460[20180912 6:41:0] [web_dump:562][DMN0]active=1,pid=1669,status=1,flag=0x0,DID0
1536734460[20180912 6:41:0] [web_dump:562][DMN1]active=1,pid=-1,status=0,flag=0x0,DID1
1536734460[20180912 6:41:0] [daemon_restart:706][DID1] remain IP server retry for 6 times.
1536734460[20180912 6:41:0] [gen_key_files:578]IN
1536734460[20180912 6:41:0] [gen_key_files:593]OUT
1536734460[20180912 6:41:0] [create_daemon_conf:605]IN
1536734460[20180912 6:41:0] [create_daemon_conf:616]cmd_buf=>dir=/
1536734460[20180912 6:41:0] [create_daemon_conf:621]cmd_buf=>cgipat=cgi-bin/**
1536734460[20180912 6:41:0] [create_daemon_conf:626]cmd_buf=>chroot
1536734460[20180912 6:41:0] [create_daemon_conf:631]cmd_buf=>user=root
1536734460[20180912 6:41:0] [create_daemon_conf:636]cmd_buf=>max_age=0
1536734460[20180912 6:41:0] [create_daemon_conf:641]cmd_buf=>debug
1536734460[20180912 6:41:0] [create_daemon_conf:648]cmd_buf=>ssl
1536734460[20180912 6:41:0] [create_daemon_conf:653]cmd_buf=>certfile=/etc/icos/ca/cert.pem
1536734460[20180912 6:41:0] [daemon_restart:748][DMN]Lanch=>/usr/sbin/iweb  -p 443 -d /www -s
1536734460[20180912 6:41:0] [notify_web:862]IN(E59|S59|D00)
1536734463[20180912 6:41:3] [notify_web:862]IN(E02|S56|D00)
1536734463[20180912 6:41:3] [msgcb_web:1218]IN(DID1,pid 2235)
<--
failed to load the session from binary
Icos_users.session_ttl: 300 sec
Icos_users.users[0].name: root
Icos_users.users[0].pass: $1$$2Dg0uARUa9gcTJ9I5/iKb/
Icos_users.users[0].level: 3
Icos_users.users[1].name:
Icos_users.users[1].pass:
Icos_users.users[1].level: 0
Icos_users.users[2].name:
Icos_users.users[2].pass:
Icos_users.users[2].level: 0
Icos_users.users[3].name:
Icos_users.users[3].pass:
Icos_users.users[3].level: 0
Starting SSL iweb on port 443, cert from /etc/icos/web/iweb_cert.pem, key from /etc/icos/web/iweb_key.pem, serving /www
-->
1536734464[20180912 6:41:4] [notify_web:862]IN(E01|S56|D00)
1536734464[20180912 6:41:4] [notify_web:862]IN(E40|S35|D00)
1536734465[20180912 6:41:5] [notify_web:862]IN(E46|S35|D00)
1536734465[20180912 6:41:5] [notify_web:862]IN(E46|S35|D00)
1536734465[20180912 6:41:5] [notify_web:862]IN(E47|S35|D00)
1536734465[20180912 6:41:5] [notify_web:862]IN(E50|S59|D00)
1536734474[20180912 6:41:14] [notify_web:862]IN(E59|S59|D00)

看來是解掉了

上 code 之後再看看也沒有時間來重構這個 module 吧

commit 9a6e3a71fa0b92d5eef394aca42750b389d2dd3a
Refs: [develop], {origin/develop}
Author: jeffrey <[email protected]>
Date:   Wed Sep 12 15:08:16 2018 +0800

    solve mantis issue 236: (Hytec) Add checking for encrypt file to avoid https start failure.

 proscend/prosrc/icos/icoslib/web/webcfg.c | 9 +++++++++
 1 file changed, 9 insertions(+)

沒有作太多的說明

目前自記對於 web module daemon control 還不算熟

像是 HTTPS 面對失效的 key 執行失敗為什麼沒有透過 msgcb_web 先回傳 output 而是直接呼叫 termcb_web

在 termcb_web 打印 msg 看看

@@ -1101,9 +1101,17 @@ static int termcb_web(char *msg, pid_t pid)

             if (gWebCtrl.dmn_ctrl[i].did == DID_HTTPS)
             {
+                if(msg)
+                {
+                    WEB_DAEMON("<--\n");
+                    WEB_DAEMON("%s",msg);
+                    WEB_DAEMON("-->\n");
+                }
+
                 remove(WEB_DAEMON_KEY_FILE);
                 remove(WEB_DAEMON_CERT_FILE);
                 gWebCtrl.dmn_ctrl[i].is_keyfile_ready = 0;
+
                 WEB_INFO("HTTPS terminate, remove key and cert and restart the daemon\n");
             }

更換 libicos.so 之後一樣故意讓 key 失效

1536735342[20180912 6:55:42] [termcb_web:1082]IN(1697)
<--
*ProcDead]failed to load the session from binary
Error starting server on port 443: Invalid SSL key
-->
1536735342[20180912 6:55:42] [termcb_web:1115]HTTPS terminate, remove key and cert and restart the daemon

看來我不下的機制的確解決了這個 issue

把 mantis 上的 issue 關掉吧

1520

目前 mantis issue 剩四條

  • 246 - [web] URL Filter suggest add "back" button
  • 245 - [WEB] MAC Filter suggest add "back" button
  • 244 - [WEB] IP filter suggest add "back" button
  • 243 - [WEB] port forwarding suggest add "back" button

這在上次開會就已經決議不採取 DQA 的建議

簡單給個禮貌地回復就關掉 issue 吧

"Save" 按鈕本身便扮演著 save 並回到 (Back) summary 畫面的功能
目前不採取 DQA 的建議
請見諒

四個 issue 就這樣都關掉了

目前 M300 待作事項只剩 GRE tunnel with NHRP

這算新的功能追加 所以等 M360 release 完再說

1530

把為了 M360 作的 usage display 搬到 M300 吧

直接 build image 來作測試

image

PASS

上 code 吧

commit a31df55627e1d4f18f40b909c080757d0222ab73
Refs: [develop], {origin/develop}
Author: jeffrey <[email protected]>
Date:   Wed Sep 12 16:06:14 2018 +0800

    use 'Used MB in 10 Seconds' to replace the 'Real Time Usage' at 'Real Time' tab in 'LTE / Usage Display' web page

 proscend/prosrc/www/app/app.module.js              |   2 +-
 proscend/prosrc/www/app/feature/usageDisplay.html  |  34 +-
 proscend/prosrc/www/app/feature/usageDisplay.js    |  92 +-----
 .../www/libs/angularjs-gauge/angularjs-gauge.js    | 366 +++++++++++++++++++++
 proscend/prosrc/www/src/index.html.src             |   2 +
 5 files changed, 404 insertions(+), 92 deletions(-)

1610

把之前在 M360 上為了不讓 SNTP client 一要到 ip 就讓 web session timeout 的修改套到 M300 去

1536740455[20180912 8:20:55] [msgcb_web:1218]IN(DID0,pid 5173)
<--
root logged in with level 3, sid ee6f903cef128d3c
-->
1536741600[20180912 8:40:0] [msgcb_web:1218]IN(DID0,pid 5173)
<--
_handler_level_normal: /cgi-bin/bgp.cgi
-->

看到 8:208:40 的 time 跳躍並沒有導致 web session timeout

觀察原本的 timeout 機制有沒有正常運作

1536741600[20180912 8:40:0] [msgcb_web:1218]IN(DID0,pid 5173)
<--
root logged in with level 3, sid ee6f903cef128d3c
-->
1536741613[20180912 8:40:13] [notify_web:862]IN(E16|S31|D00)
1536741903[20180912 8:45:3] [msgcb_web:1218]IN(DID0,pid 5173)
<--
Session ee6f903cef128d3c (root) closed due to idleness.
-->

PASS

上 code

commit a8a76138799f8039c94f41b02a33e4863c24495d
Refs: [develop], {origin/develop}
Author: jeffrey <[email protected]>
Date:   Wed Sep 12 16:46:36 2018 +0800

    use SysGetUpTime() instead of mg_time() except within mg_set_timer():

    if you login via web ui before sntp client get the time,
    after sntp client get the time, your web session will timeout immediately.

    Because the difference between the lasted login timestamp and the current timestamp exceeds our threshhold.

    So we use SysGetUpTime() to get rid of impact of the time updating.

    We can not use SysGetUpTime() within mg_set_timer(), or mg_set_timer() will not trigger MG_EV_TIMER event in the correct time

 proscend/prosrc/icos/iweb/iweb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

1650

感覺我可以把為了 M300 HTTPS key 套到 M360 來

切回 M360 工作