大家好
今天要來跟大家介紹一下這個作業的想法
以及如何實作
●本次作業說明:
第一:實作一個SOCK4 Server,能夠支援Connect/Bind mode兩種模式,並實作出防火牆的功能
第二:在HW3的CGI程式中,加入連線到SOCK Server的功能
((沒有隱藏測資喔喔喔喔喔
((這次爽拿100分喔喔喔喔
●想法:
Connect/Bind mode:
參考標準,照樣填入對應的資料reply回去
防火牆:
根據socks.conf中的設定,來取決於要不要繼續進行連線
格式為permit ( mode type:b(bind mode), c(connect mode) ) (IP address)
重點就是檔案讀取&字串處理啦
CGI+socks:
加一些關於SOCKS的判斷式,看是否要啟用SOCKS連線
(這部分的詳細說明之後補上,簡單來說就是先判斷網頁空格有無填入SOCKS server的位址,有的話就要先做SOCKS的事情,再做CGI的事情)
●我的架構:
第一:sock.cpp
第二:把HW3的cgi & httpd通通複製過來
●流程:
如同先前寫的server
要先建立好socket
並且bind & listen
再來等使用者連線進來accept
就fork出child process進去handle_socket()處理要求
((記得parent不要wait child,這樣一次只能處理一筆連線,只要那個連線等不到response,程式就會動不了,這個錯誤de了一個晚上才發現))
進來後
"請務必用unsigned char去read"
因為網路協定的傳輸都是用unsigned char type的方式傳輸
用char去接的話...嘿嘿嘿
你會發現SOCKS完全動不了
((這個問題也找了很久才發現
將VN、CD、DST_IP和DST_PORT填好
並且預留USER_ID這個部分
((這個部份我不知道它的用途是啥,在這次的作業都是NULL
接著就判斷此連線的DST_IP是否可以通過防火牆
先開好sock.conf後
用一個while迴圈去掃
並且和DST_IP比對
有符合允許的位址的話,reply的第一格就填0x5A
你覺得不行的話,reply的第一格填0x5B(reject掉)
然後判斷是Connect還是Bind mode做對應的回覆
-----------------------------------------------------------------------
※Connect mode(CD=0x01)
建立與目標server的socket後連線
reply的內容:
第0格填0(代表這訊息為SOCK4 reply)
第2~7格就照request的內容填進去
因為DST_IP,DST_PORT都和request一樣(到目標伺服器)
※Bind mode(CD=0x02)
由SOCK server選一個port給client program bind
用getsockname()抓出port,傳reply(IP填0,PORT填SOCKS bind的port number)給client
reply的內容:
第0格填0
第2~3格填入SOCKS bind的port number
第4~7格填0
client會利用前面connect mode的連線告訴target server,要自動連來SOCKS server剛bind的port
target server連過來SOCKS後,再傳一次一模一樣的reply給client
-----------------------------------------------------------------------
接下來兩者都會做像是HW2 single process的事情
將連到SOCK server的fd、SOCK server連到目標伺服器的fd加入fd_set
並用select去看是哪個fd有資料要傳
擔任一個中繼端的角色協助資料傳遞
也就是:
先將target server/client的資料收下來,再轉送到client/target server
這樣就大功告成囉~~
有問題歡迎提問
程式參考連結:
https://lsps4111wu@bitbucket.org/lsps4111wu/np_project4_0656509
FTP運作模式:
http://matis.pixnet.net/blog/post/22918494