7 레이어-2 프로토콜들로부터 정보를 받기
몇 개의 라우팅 프로토콜들은 패킷이 레이어-2로부터 보내질 수 없을 때 반응에 흥미가 있을 것이다. 이것은 우리가 아래에 설명한 것처럼, 우리의 라우팅 에이전트에 의해서 쉽게 달성될 수 있다.
그것은 어떻게 작동하는가? 패킷의 공통의 헤더는 그 패킷이 그 레이어-2 에이전트에 의해서 보내질 수 없다면 호출될 것인 함수를 네가 명시할 수 있는 필드를 가진다. 그 함수를 protoname_mac_failed_callback()이라 부르자. 우리는 그런 레이어-2 실패에 대해 반응을 담당하는 역할을 하는 라우팅 에이전트 내에 또 다른 것을 호출하는 이런 함수를 사용할 것이다. 우리는 이런 두 번째 함수를 mac_failed()로 부를 것이다. 그래서 우리는 protoname/protoname.h의 줄 9만 단지 변경해야 한다
protoname/protoname.h
1: class Protoname : public Agent {
2: /* … */
3:
4: public:
5:
6: Protoname(nsaddr_t);
7: int command(int, const char*const*);
8: void recv(Packet*, Handler*);
9: void mac_failed(Packet*);
10: };
11: #endif
그 protoname/protoname.cc 파일은 더 많은 변화들을 요구한다. 무엇보다도 우리는 공통의 헤더 안쪽에 등록되는 그 함수를 구현해야 한다. 그 함수는 Protoname 클래스의 mac_failed() 함수로 단순히 호출할 것이다. 너는 아래에 구현을 볼 수 있다.
protoname/protoname.cc
1: static void
2: protoname_mac_failed_callback(Packet *p, void *arg) {
3: ((Protoname*)arg)->mac_failed(p);
4: }
mac_failed()에 의해서 구현된 기능성은 protoname 규격에 매우 의존한다. 예를 들어, 코드의 다음 조각은 디버그 메시지를 프린트하고 (줄 6-9) 패킷을 버린다. (줄 11)
protoname/protoname.cc
1: void
2: Protoname::mac_failed(Packet* p) {
3: struct hdr_ip* ih = HDR_IP(p);
4: struct hdr_cmn* ch = HDR_CMN(p);
5:
6: debug(“%f: Node %d MAC layer cannot send a packet to node %dn”,
7: CURRENT_TIME,
8: ra_addr(),
9: ch->next_hop());
10:
11: drop(p, DROP_RTR_MAC_CALLBACK);
12:
13: /* … do something … */
14: }
만약 우리가 라우팅 패킷이 레이어-2 프로토콜들에 의해서 보내지지 않을 때를 알기 원한다면 우리는 send_protoname_pkt()를 변경할 필요가 있다. 유사하게 만약 우리가 데이터 패킷들에 주의하기를 원한다면 forward_data()는 가볍게 마찬가지로 변경되어야 한다. 양쪽의 경우들에서 우리는 그 패킷의 공통의 헤더를 업데이트할 때 다음의 두 개의 줄들을 단지 더해야 한다.
protoname/protoname.cc
1: ch->xmit_failure_ = protoname_mac_failed_callback;
2: ch->xmit_failure_data_ = (void*)this;
protoname_mac_failed_callback()은 무슨 경우들에서 호출될 것인가? NS-2.27에서 우리는 두 개의 다른 상황들을 설립할 수 있다.
mac/arp.cc 노드가 목적지 주소를 (ARP를 통해서) 결정하기를 원하지만 재시도들의 최대 숫자가 초과될 때
mac/mac-802_11.cc 두 개의 가능성들이 있다. 첫 번째 것은 RTS가 보내졌지만 대응하는 CTS가 받아들여지지 않았고 재시도의 최대 숫자가 초과될 때 일어날 수 있다. 두 번째 것은 데이터 패킷이 전달되었지만 절대 ACK를 받지 못했고 (받아들여진 ACK가 없다) 재시도들의 최대 숫자가 초과될 때 발생한다.
8 유선이-붙은-무선 환경들을 위한 지원
이제까지 우리는 평평한 manet들, 즉, 무선-유일한 시나리오들에 대해서만 관련이 있었다. 이번 절에서 우리는 하이브리드 manet들 (NS2 용어를 따르면, 유선이-붙은-무선 시나리오들)을 다루기 위한 기본적인 개념들을 소개할 것이다. 유선이-붙은-무선 스크립트들은 계층적인 주소를 사용할 필요가 있고, 그래서 너는 주소의 이런 유형에서 필요한 지식을 얻기 위해서 15장과 29장 [2]을 읽어야 한다.
최소의 변화들과 함께 우리는 유선이-붙은-무선 시뮬레이션들에서 우리의 프로토콜을 사용할 수 있다. 이런 것들에서는 고정된 노드들, 무선 노드들 그리고 베이스 스테이션들이 있다. 베이스 스테이션은 유선과 무선 도메인들 사이에 게이트웨이이고, 모든 무선 노드는 자신이 어느 베이스 스테이션에 결합되는지를 알 필요가 있다. 우리가 유선이-붙은-무선 지원을 제공하기 위해서 실행할 필요가 있는 모든 것은 각각의 노드를 위해 일치하는 베이스 스테이션을 설정하는 것이다.
유선이-붙은-무선 시나리오들을 기술하는 시뮬레이션 스크립트들은 각각의 모바일 노드에서 시간적으로 앞선 동작을 수행하는데, 즉, 모든 모바일 노드는 베이스 스테이션 (노드 API의 베이스-스테이션 함수)에 부착된다. 그러나 우리는 여러 개의 베이스 스테이션들이 사용되는 시나리오들에 관심이 있고, 우리는 모바일 노드들이 그들의 결합된 베이스 스테이션들을 동적으로 바꾸기를 원한다는 것을 상상해라. 우리가 다수의 베이스 스테이션들이 허락되는 하이브리드 ad hoc 네트워크들을 지원하는 라우팅 프로토콜을 코드하기를 원한다면 이것은 유용하다. 만약 이것이 너의 경우라면, 그 절을 계속해서 읽어라.
다음의 코드에서 보여지는 것처럼 protoname/protoname.h를 다시 편집하자. 줄들 1과 11은 더해지고, 반면에 나머지는 변하지 않는다.
protoname/protoname.h
1: #include <mobilenode.h>
2:
3: /* … */
4:
5: class Protoname : public Agent {
6:
7: /* … */
8:
9: protected:
10:
11: MobileNode* node_;
12:
13: /* … */
14: };
우리는 라우팅 에이전트가 부착되는 노드를 의미하는 (common/mobilenode.h에서 정의된) 모바일노드 오브젝트에 대한 참조를 더했다. 이런 참조를 얻기 위해서 우리는 Protoname 건설자 안쪽에 다음의 줄 4를 더할 필요가 있다.
protoname/protoname.cc
1: Protoname::Protoname(nsaddr_t id) : Agent(PT_PROTONAME), pkt_timer_(this) {
2: bind_bool(“accessible_var_”, &accessible_var_);
3: ra_addr_ = id;
4: node_ = (MobileNode*)Node::get_node_by_address(id);
5: }
모바일노드 클래스는 우리가 관심이 있는 두 개의 함수들을 소유한다. 우선 첫째로 모바일 노드가 부착되는 베이스 스테이션의 식별자를 되돌려주는, base_stn()이다. 두 번째는 그 모바일 노드를 위한 적합한 베이스 스테이션을 설립할 수 있는 set_base_stn()이다. 그래서 우리는 유선이-붙은-무선 시뮬레이션들을 이런 두 개의 함수들을 사용함으로써 다룰 수 있다. 예를 들어, 다음의 코드는 그 모바일 노드 자체가 베이스 스테이션인지를 체크하고; 만약 아니라면 그때 그것은 베이스 스테이션을 할당 받는다.
protoname/protoname.cc
1: if (node_->base_stn() == ra_addr()) {
2: // I’m a base station
3: /* … */
4: }
5: else {
6: // I’m not a base station
7: node_->set_base_stn(base_stn_addr);
8: }
앞의 예제는 결합된 베이스 스테이션을 동적으로 바꾸는 법을 보여준다. 이런 바꿈들을 수행하기 위해서 사용되는 접근들은 프로토콜 자체에 의존한다.
참조
[1] Marc Greis. Tutorial for the Network Simulator ”ns”.
http://www.isi.edu/nsnam/ns/tutorial/index.html.
[2] The VINT Project. The ns Manual, December 2003.
http://www.isi.edu/nsnam/ns/ns-documentation.html.
[1] 이것은 manet 라우팅 프로토콜들에서 일반적인 특징이지만, 그러나 실제 목적은 랜덤 숫자들을 얻는 예제를 제공하는 것이다.
[2] 실제 이것은 사실이 아니다. 사실 데이터 패킷들은 자신들의 일치하는 에이전트에게 직접 배달되고, 그래서 포트 분류자는 우리의 라우팅 에이전트에서 필요하지 않다. 그러나 우리는 이런 설명을 유지하는데 왜냐하면 NS-2.27은 라우팅 에이전트가 자신의 API의 부분으로써 port-dmux 동작 (4.3.2절을 보라)을 받아들이는 것을 요구하기 때문이다.
[3] IP 헤더에 따라서 패킷의 Time To Live