顯示具有 網路程式設計 標籤的文章。 顯示所有文章
顯示具有 網路程式設計 標籤的文章。 顯示所有文章

2018年2月14日 星期三

[教學&詳解] Network Programming HW4 - SOCK4 Server + Firewall


大家好
今天要來跟大家介紹一下這個作業的想法
以及如何實作

●本次作業說明:
第一:實作一個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

2018年1月11日 星期四

[教學&詳解] Network Programming HW1 - Remote Access System

大家好
剛從NP期末考爆炸的小弟
要來跟大家介紹一下這個作業的想法
以及如何實作
程式coding style如果有需要改進之處歡迎留言讓我知道XDD

(後續3個作業慢慢更新)

●本次作業說明:
實作一個shell,具有pipe + number pipe + file output 的功能
number pipe在用
本次的重點就是pipe的使用

●想法:
需要有一個能夠管理pipe的class
決定該指令的in, out, error要從哪裡來/往哪裡去
※pipe開關的原則
→在parent的部分
1.pipe進來的:關掉進來的write,fork後parent再把他的read關掉
(如果fork之前關掉,child就沒辦法讀pipe的東西了)
2.pipe出去的:不用關,因為可能還有其他指令要寫入這個pipe
→在child的部分
把stdin,stdout,stderr導入正確的pipe後
read, write都要關閉

●我的架構:
socket.cpp:負責處理連入連線
server.cpp:負責處理所有的ras要求
types.cpp:自定義的class都放在這

自定義的class包含了
1. SingleCmd
顧名思義就是一個指令的資料
紀錄了...
執行檔的名稱(execute)
是否需要pipe(need_pipe)
要往後pipe幾個指令(pipe_num)
並且有三個member function
push():在parse指令的時候用
get_exe()、get_argv():這兩個在exec的時候轉回所需的型態

2. LineCmd
這是存一整行所有指令的class
有一個vector<SingleCmd>存這一行所有的指令
有一個member function add_cmd()負責把一行內的單一指令打包

3. PipeAdmin
有一個pipe_set存1000格pipe陣列
有四個member function
create_pipe//初始pipe
void close_pipe//關閉pipe的read or write端
int find_pipe(int);//找到在1000個pipe中和pipe_num相同剩餘的pipe位置
void decr_num();//減少所有pipe的pipe_num


●流程:
e.g. 有一行指令為 removetag test.html | cat > a.txt

先從socket.cpp開始
將socket建立後,bind在指定的port並listen,直到有連線進來時呼叫accept
並且fork一個child process負責處理這個連線,就進入do_ras處理指令
(這裡fork的用意是為了下一個作業需要多人連線,預先寫好的)
do_ras會先切割指令(cmd_parse)→執行指令(run)

※cmd_parse
一開始先從client讀指令過來
將收到的字串轉換成string開始切指令
我根據"|"和">"做為切割的符號
藉由string的find_first_of()找到符號位置存入place變數

如果有找到上述兩個符號的話
就進入while迴圈
抓取從頭到place位置的字串內容
放到新的string sub_str之中
並藉由stringstream會自動看空白切字串的特性
把字串push到SingleCmd之內

接著去判斷place所指的符號為何
如果是|
就用isdigit判斷pipe後一格的是否為數字
若是就把它用atoi轉換成數字存入SingleCmd的pipe_num
不是的話pipe_num就設定為1
如果是>
因為在本次作業中必定是一行之中最後一個指令
因此只要存後面要輸出的檔案名稱
並且把toFile的flag設為true
上面的if做完之後
再判斷一次後面有沒有|或>的符號
沒有就跳出函式

※run
把剛剛parse完的LineCmd用迴圈去go through
先挑出不需要用到pipe的三個指令(setenv, printenv, exit)

接下來藉由呼叫check_exe這個函式
判斷這個cmd的名字有沒有在ras/bin底下
如果沒有的話直接輸出"Unknown command"

然後是針對output部分
判斷要pipe過去的地方是否已經有指令pipe過去
如果沒有的話要把那一格pipe做初始化的動作

最後就是fork出要拿來exec的process
根據上面想法所提及的方式
將stdin, stdout, stderr dup2去正確的地方
呼叫exec執行指令
並在parent這邊呼叫wait等到指令執行結束
(避免zombie process)


程式參考連結:
https://lsps4111wu@bitbucket.org/lsps4111wu/np_project1_0656509