網頁

2014年5月23日 星期五

如何使用Makefile recursive make

- 問題:
如何使用make來使makefile recursive make ?
(也就是你有一個project此project又由各個子component組成)


-- 單純只make的方法:
使用 make -C
注意: $(SUBDIR)一定要設.PHONY不然不會有任何執行的動作


-- 如果要套用make clean和make install到各個子目錄又該如何寫?
方法有點tricky,我們在上面使用 $(SUBDIR)的方式就好像使用for迴圈一樣一個個目錄進去make。
但是有個問題: 如果make all了但是邏輯網下走$(SUBDIR)時我們就無法分辨: make all, make install, 還是make clean的情況.
http://lackof.org/taggart/hacking/make-example/的作者就提出一個方法: 讓各個targets(all, install, clean)有自己的$(SUBDIR)。
當進入自己的$(SUBDIR)時才真的做字串的替換。這樣子就可以解掉使用make -C只能make all的問題。


注意: 題外話作者不建議在makefile使用for的方式一個個進去make。因為其缺點就是
- 1. 無法享有concurrent make的好處。而且
- 2. 如果有make fail也不會停下來。

-- Ref:

2014年5月20日 星期二

DDNS原理

什麼是DDNS ?
Dynamic DNS



為什麼需要DDNS ?
一般來說是以下兩種理由
1. 因為架站的對外ip不斷改變(譬如說使用PPPoE浮動IP對外連線)
2. 因為申請Domain name很貴



使用DDNS的壞處?
1. 如果DDNS provider掛了,你的網頁就掛了。所以一個穩定的DDNS提供者是很重要的。
2. 寄人籬下,domain name一定是你的DDNS provider結尾。譬如說: no-ip.org



DDNS的原理 ?
原理相當簡單,其實大部分就是和一般的DNS一樣,不同的地方在於:
1. DDNS server上的DNS zone cache時間要盡量設小
知道DNS的人,都知道zone的data會被其他的DNS server cache住。因此要用DNS實現DDNS的先決條件就是: 架DDNS server的DNS zone cache時間設定要設最小。以免當其他不是經由這一個DNS server查詢到ip資訊而是向其他的DNS server查詢到。

2. DDNS client端需要有一個deamon,當ip改變時要去通知DDNS server已改變。當然DDNS server也必須要有能力接收這個資訊,以及能夠自動化更新ip。(我想這個部份應該是描述在: http://tools.ietf.org/html/rfc2136 有興趣的可以自己去看)

2014年5月18日 星期日

空氣品質偵測


昇儀 - 室內空氣品質偵測

室內空氣品質(gov), 什麼是IAQ ?


---------------------------------供應商------------------------------------------
費斯multiflow

暉耀

耀群

良興購物網 - 氧氣/瓦斯偵測販賣


ipone/andriod 二氧化碳偵測 Netatmo
Netatmo官方網站

----------------------------------解決方案----------------------------------------------------
TED提供 - 自然方法 - 養殖 黃椰子 虎尾蘭 黃金葛

其他方法
全熱式交換器

2014年5月15日 星期四

動態的將element加入dom

舉例來說
我們可以在javascript建立這樣的box component然後內嵌 html

                     xtype: 'box',  
                     html: '<img src='+ xxxi.png', '') +'style="vertical-align:bottom;" border="0" ext:qtip="'+Ext.util.Format.htmlEncode("xxxx"))+'">'  

以上的code也可以用另外一種更動態的方式實做(dom的操作)。

大概會用到下面幾個functions
document.createElement
Ext.getCmp
element.setAttribute

首先先建立 a element
接下來再建立img element
     var tip_header = document.createElement("a");  
     var tip_image = document.createElement("img");  

一開始先用目標的obj id得到 component
 var field = Ext.getCmp(obj.id);  

然後以下的屬性
1. img src
2. style
3. width/height
4. qtip
都可以用 setAttribute的方式設定進去
如下:
     tip_image.setAttribute('src', 'xxxxx.png', ''));  
     tip_image.setAttribute('width', '10px');  
     tip_image.setAttribute('height', '10px');  
     tip_image.setAttribute('style', style);  
     tip_image.setAttribute('ext:qtip', message);  

最後把img append為a的child
然後再把a append為目標obj的parent的child如下:
 tip_header.appendChild(tip_image);  
 Ext.getDom(obj).parentNode.appendChild(tip_header);  

利用以上這樣的手法我們就可以動態的把dom element加入dom tree就好像內嵌html一樣

2014年5月12日 星期一

創業

基於很多原因,我想要在職創業。

前提是不影響到目前的工作。而我想要創業的目標是類似於whocalls這種型態的小軟體。
為什麼?因為沒錢也沒有太多時間,我預估我一個禮拜大概會有半天到一天的自由時間,而若是發展熟悉領域的軟體,一天大約可以寫500〜1000行的程式碼。以我的毅力來看,我可以持續一年吧?這樣的推估就是我大概有辦法發展出一個小規模的軟體。

這樣推估完,剩下的問題就是,題目。

最近看到whoscall的發跡,其實頗有感想的。
這就好像寫論文一樣,當別人發了一個很好的想法後,會驚訝自己從來沒想過。
而我這次的心得是:「你覺得沒什麼的,你覺得沒有那麼迫切需要的,也許都有它的價值,反過來說,你覺得很有用的,迫切需要的,也許沒有你想的這麼有價值。」

因為決定是否有價值的,就是是否有那樣的巿場?是否這個世界上有存在那麼多的客戶?來決定。

祝你我都能找到一個有價值的好題目。

2014年5月11日 星期日

tcp udp hole punching

Env ?


  • no limitation. (windows, unix/linux, mac ...)
  • The only limitation is it is "socket programming".


What is it ?


  • This is a trick for TCP hole punching defined in the RFC tcp spec3.4. Establishing a connection
    • There are two ways to establish a connection.
      • The first method is "accept()...connect()".
      • The second method is "connect()...connect()".
    • We discuss here is the second method.
  • Use this tech you can conquer NAT issue.
  • This method is also called p2p tcp hole punching.


How to use it ?


  • As Peer-to-Peer Communication across NAT 4. TCP hole punching explains, we can use "connect()...connect()" to do tcp hole punching.
  • The example code is simple:
    • tcp_hole_punching_client.c
    • while (connect(s, (struct sockaddr *)&serverAddr, sizeof(serverAddr))) {
          printf("\n[%d]", connect_times++);
          perror("connect failed");
          usleep(1000+(rand()%1000));
      }
      
  • You may have some questions after read above code:
    • 1. why use "while" to connect ? 2. why need to use usleep ?
      • Ans: Before this, you need to know how does it work ?

How does it work?

  • If each client send SYN to each other simultaneously, we can imagine for the left side when it sends out SYN packet, it will allow packets which are the destination of the SYN packet to send in some packets. For the right side, it also does.
  • So that the TCP hole punching can be established by this way.

Pre-condition


  • The router type is "preserves port" type and should not be
    • Random port type
    • Symmetric (NAT cones, please refer NAT wifki)


2014年5月10日 星期六

use LD_PRELOAD to patch your program

Env ?

  • Linux/Unix platform.
  • C/C++

What is it ?
  • You can set env variable LD_PRELOAD to "replace" the binary program's functions/subroutines with the functions/subroutines which are defined in the .so shared libraries specified in LD_PRELOAD.

How to use it ?

  • For example, if we want to replace "malloc" function of "ls" program with our own defined function.
    • Step1: write our self-defined malloc and compile it as .so shared library.
      • vim mylib.c:
      • #include <stdio.h>
        void* malloc(size_t size) {
            printf ("hello\n");
            return NULL;
        }
        
        
      • compile mylib.c as shared library
      • gcc -Wall -fpic -shared -o libmylib.so mylib.c
        
    • Step2: Run it !
      • Replace ls "malloc" with our own defined "malloc" in shared library
      • LD_PRELOAD=./libmylib.so /bin/ls
    • Result
      • hello
        hello
        hello
        hello
        hello
        hello
        hello
        /bin/ls: memory exhausted

Usage ?

  1. I guess for hacker/cracker it may be an important skill.
  2. We can fast replace the function with our defined function although we do not have source code.(patching/wrap function)



setjmp and longjmp


  •  What is it ? (setjmp / longjmp)
    • This is basic function on unix/linux platform. With these two functions you can simulate the functionality like "try/catch" in C++ or Java programming language.
    • 簡單來說就是c語言版本的try/catch啦。

  • How to use it ? (example)
    • Description:
      • You can include setjmp.h in your code. After declare your own "jmp_buf"(in the local or global), you can call setjmp() and input this variable into this function in your code to save your current registers status like "program counters" into "jmp_buf".  This first argument of setjmp is "jmp_buf". After setjmp() returns, the "jump_buf" has the content of current registers status. And at this time, setjmp() returns "0".
      • And then you can call longjmp() later in your code.
      • After you call longjmp() in your code you will "goto or jump to" the location of setjmp() in your code. At this time, setjmp() returns what you inputs in your longjmp's second argument. 
      • NOTE: Do not use longjmp() before setjmp(), the behavior is undefined.
      • 簡單來說就是先呼叫 setjmp() 再呼叫longjmp(),詳情可以參考上面的example連結的範例。
      • 第一次呼叫setjmp()是用來把目前暫存器的值存入jmp_buf,這次setjmp是回傳0。
      • 之後呼叫longjmp()時就可以把此jmp_buf的值載入回暫存器。此時在longjmp()的第二個參數可以填入setjmp()的回傳值。
      • 呼叫完longjmp()後因為暫存器的值被載入回去,所以此時的program counter也會變回呼叫setjmp()時的PC值。
      • 這一次setjmp()就會返回你在longjmp()第二個輸入的參數值。
  •  How to implement it ?
    • The basic concept is like I mentioned above: 
      • Save all program register when call setjmp()
      • Load all program register when call longjmp()
    • For the more detail implementation description can refer here.
    • 原理其實很簡單,就是在呼叫setjmp()時會把一堆register的值存到jmp_buf裡面。而在longjmp()時再把jmp_buf裡面的值填回registers.可以參考這邊here.