unbound原始碼分析

Lht1發表於2024-03-31

unbound原始碼分析

版本: 1.17.2

編譯選項: ./configure --prefix=your_path --enable-subnet --enable-debug --with-libevent

請求呼叫棧:

看了worker_handle_request的原始碼,unbound也是存在ip維度的限速的。

dig qq.com @127.0.0.1

worker_init初始化執行緒變數worker

在comm_base_set_slow_accept_handlers方法中傳入worker_stop_accept和worker_start_accept函式指標以及worker,並設定到worker->base->stop_accept和worker->base->start_accept,worker->base->cb_arg。

在呼叫accpet相關函式指標時,就會傳入worker->base->cb_arg。

設定worker->comsig的訊號回撥函式為worker_sighandler。處理訊號為SIGHUPSIGINTSIGQUITSIGTERM

設定worker->front為listen_create返回值(接收使用者請求),主要回撥方法是worker_handle_request

回撥方法原型:typedef int comm_point_callback_type(struct comm_point*, void*, int, struct comm_reply*);

unbound使用struct comm_point來表示一個監聽的socket。

  • tcp型別的comm_point建立透過comm_point_create_tcp方法。其accept回撥為comm_point_tcp_accept_callback
  • udp型別的comm_point建立透過comm_point_create_udp方法。其回撥為comm_point_udp_ancil_callback

unbound worker透過worker_handle_control_cmd來執行命令控制。

每個worker裡面存在back欄位來向權威伺服器發起遞迴,主要是在worker_init方法中呼叫outside_network_create方法來初始化。

unbound的lruhash資料結構:動態增長的雜湊表(當元素數量等於陣列長度時,擴容為原來的2倍),採用lru機制來限制雜湊表的記憶體使用量,當超過最大記憶體使用量時淘汰最少使用的元素。(原理跟java中的linkedhashmap差不多)

slabhash則是對lruhash進行一層封裝,內部用陣列存放多個lruhash,再進行一層hash,把資料分散到不同lruhash中。

unbound的region資料結構:記憶體分配緩衝區,分配的記憶體大於large_object_size時,就呼叫malloc方法分配記憶體,然後用large_list儲存為單連結串列節點,如果當前需要的記憶體大小大於available時,就malloc分配一塊8192位元組大小的記憶體塊,然後用next儲存為單連結串列節點,使用data儲存當前分配的記憶體塊,然後從記憶體塊中劃分一塊記憶體出去。

unbound接收請求後,最後會儲存為一個mesh事務樹,然後依次呼叫subnet模組查ecs快取、iterator模組發起遞迴請求。(方法mesh_run)

遞迴查詢:iter_operate方法

  • process_handle -> iter_handle
  • iter_handle -> processInitRequest -> processQueryTargets -> worker_send_query -> outnet_serviced_query -> serviced_create(設定定時器,預設第一次觸發就傳送資料)
  • process_response -> iter_handle -> processQueryResponse

超時回撥:serviced_timer_cb、響應回撥:worker_handle_service_reply

選路演算法:

iter_server_selection

第一次傳送資料:

serviced_timer_cb -> serviced_udp_send -> pending_udp_query(建立一個pending_udp_timer_cb的定時器) -> randomize_and_send_udp -> comm_point_send_udp_msg

響應路徑:

comm_point_udp_ancil_callback -> outnet_udp_cb -> serviced_udp_callback -> serviced_callbacks -> worker_handle_service_reply -> mesh_report_reply -> mesh_run -> iter_operate -> process_response -> iter_handle -> processQueryResponse -> processFinished -> mesh_continue -> mesh_query_done -> mesh_send_reply -> comm_point_send_reply

相關文章