File: DHCPRelay.cpp

package info (click to toggle)
dibbler 1.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 13,352 kB
  • sloc: cpp: 60,323; ansic: 12,235; sh: 11,951; yacc: 3,418; lex: 969; makefile: 940; perl: 319; xml: 116; python: 74
file content (126 lines) | stat: -rw-r--r-- 3,110 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Dibbler - a portable DHCPv6
 *
 * authors: Tomasz Mrugalski <thomson@klub.com.pl>
 *          Marek Senderski <msend@o2.pl>
 *
 * released under GNU GPL v2 licence
 *
 */
      
#include <stdlib.h>
#include "DHCPRelay.h"
#include "Logger.h"
#include "Portable.h"
#include "RelIfaceMgr.h"
#include "RelCfgMgr.h"
#include "RelTransMgr.h"
#include "RelMsg.h"

using namespace std;

volatile int serviceShutdown;

TDHCPRelay::TDHCPRelay(const std::string& config)
{
    serviceShutdown = 0;
    srand((uint32_t)time(NULL));
    IsDone = false;

    TRelIfaceMgr::instanceCreate(RELIFACEMGR_FILE);
    if ( RelIfaceMgr().isDone() ) {
        Log(Crit) << "Fatal error during IfaceMgr initialization." << LogEnd;
        this->IsDone = true;
        return;
    }
    RelIfaceMgr().dump();

    TRelCfgMgr::instanceCreate(config, RELCFGMGR_FILE);
    if ( RelCfgMgr().isDone() ) {
        Log(Crit) << "Fatal error during CfgMgr initialization." << LogEnd;
        this->IsDone = true;
        return;
    }
    RelCfgMgr().dump();

    TRelTransMgr::instanceCreate(RELTRANSMGR_FILE);
    if ( RelTransMgr().isDone() ) {
        Log(Crit) << "Fatal error during TransMgr initialization." << LogEnd;
        this->IsDone = true;
        return;
    }
    RelIfaceMgr().dump();
    RelTransMgr().dump();
}

void TDHCPRelay::run()
{
    bool silent = false;
    while ( (!isDone()) && (!RelTransMgr().isDone()) ) {
    	if (serviceShutdown)
	    RelTransMgr().shutdown();
	
	RelTransMgr().doDuties();
	unsigned int timeout = DHCPV6_INFINITY/2;
	if (serviceShutdown)
            timeout = 0;
	
	if (!silent)
	    Log(Debug) << "Accepting messages." << LogEnd;

#ifdef WIN32
	// There's no easy way to break select, so just don't sleep for too long.
	if (timeout>5) {
	    silent = true;
	    timeout = 5;
	}
#endif
	
	SPtr<TRelMsg> msg = RelIfaceMgr().select(timeout);
	if (!msg) 
	    continue;
	silent = false;
	int iface = msg->getIface();
	SPtr<TIfaceIface> ptrIface;
	ptrIface = RelIfaceMgr().getIfaceByID(iface);
	Log(Notice) << "Received " << msg->getName() << " on " << ptrIface->getName() 
		    << "/" << iface;
	if (msg->getType()!=RELAY_FORW_MSG && msg->getType()!=RELAY_REPL_MSG)
	    Log(Cont) << hex << ",trans-id=0x" << msg->getTransID() << dec;
	Log(Cont) << ", " << msg->countOption() << " opts:";
	SPtr<TOpt> ptrOpt;
	msg->firstOption();
	while ( ptrOpt = msg->getOption() ) {
	    Log(Cont) << " " << ptrOpt->getOptType(); 
            // uncomment this to get detailed info about option lengths Log(Cont) << "/" << ptrOpt->getSize();
	}
	// Log(Cont) << ", " << msg->getRelayCount() << " relay(s).";
	Log(Cont) << LogEnd;
	RelTransMgr().relayMsg(msg);
    }
    Log(Notice) << "Bye bye." << LogEnd;
}

bool TDHCPRelay::isDone() {
    return this->IsDone;
}

bool TDHCPRelay::checkPrivileges() {
    /// @todo: check privileges
    return true;
}

void TDHCPRelay::stop() {
    serviceShutdown = 1;
	Log(Crit) << "Service SHUTDOWN." << LogEnd;

}

void TDHCPRelay::setWorkdir(std::string workdir) {
    RelCfgMgr().setWorkdir(workdir);
    RelCfgMgr().dump();
}

TDHCPRelay::~TDHCPRelay() {
}