Line data Source code
1 : /*
2 : * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include <algorithm>
7 : #include <boost/uuid/uuid_io.hpp>
8 : #include <base/parse_object.h>
9 : #include <ifmap/ifmap_link.h>
10 : #include <ifmap/ifmap_table.h>
11 : #include <vnc_cfg_types.h>
12 : #include <agent_types.h>
13 :
14 : #include <cmn/agent_cmn.h>
15 : #include <cfg/cfg_init.h>
16 : #include <oper/instance_task.h>
17 : #include <oper/crypt_tunnel.h>
18 : #include <oper/agent_sandesh.h>
19 : #include <oper/config_manager.h>
20 : #include <oper/nexthop.h>
21 :
22 : using namespace autogen;
23 : using namespace std;
24 :
25 : SandeshTraceBufferPtr
26 : CryptTunnelTraceBuf(SandeshTraceBufferCreate("CryptTunnel", 5000));
27 :
28 : const std::string CryptTunnelTask::kCryptTunnelCmd
29 : ("/usr/bin/contrail_crypt_tunnel_client.py");
30 :
31 :
32 : CryptTunnelTable *CryptTunnelTable::crypt_tunnel_table_;
33 :
34 0 : bool CryptTunnelEntry::IsLess(const DBEntry &rhs) const {
35 0 : const CryptTunnelEntry &a = static_cast<const CryptTunnelEntry &>(rhs);
36 0 : return (remote_ip_ < a.remote_ip_);
37 : }
38 :
39 0 : string CryptTunnelEntry::ToString() const {
40 0 : return remote_ip_.to_string();
41 : }
42 :
43 0 : DBEntryBase::KeyPtr CryptTunnelEntry::GetDBRequestKey() const {
44 0 : CryptTunnelKey *key = new CryptTunnelKey(remote_ip_);
45 0 : return DBEntryBase::KeyPtr(key);
46 : }
47 :
48 0 : void CryptTunnelEntry::SetKey(const DBRequestKey *key) {
49 0 : const CryptTunnelKey *k = static_cast<const CryptTunnelKey *>(key);
50 0 : remote_ip_ = k->remote_ip_;
51 0 : }
52 :
53 0 : void CryptTunnelEntry::PostAdd() {
54 0 : UpdateTunnelReference();
55 0 : ResyncNH();
56 0 : }
57 0 : void CryptTunnelEntry::ResyncNH() {
58 0 : Agent *agent = static_cast<CryptTunnelTable *>(get_table())->agent();
59 : typedef std::list<TunnelType::Type> TunnelTypeList;
60 0 : TunnelTypeList type_list;
61 0 : type_list.push_back(TunnelType::MPLS_GRE);
62 0 : type_list.push_back(TunnelType::MPLS_UDP);
63 0 : type_list.push_back(TunnelType::VXLAN);
64 0 : for (TunnelTypeList::const_iterator it = type_list.begin();
65 0 : it != type_list.end(); it++) {
66 0 : DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
67 : TunnelNHKey *tnh_key =
68 0 : new TunnelNHKey(agent->fabric_vrf_name(), agent->router_id(),
69 0 : remote_ip_.to_v4(), false, *it);
70 0 : tnh_key->sub_op_ = AgentKey::RESYNC;
71 0 : nh_req.key.reset(tnh_key);
72 0 : agent->nexthop_table()->Process(nh_req);
73 0 : }
74 0 : }
75 :
76 0 : void CryptTunnelTable::Process(DBRequest &req) {
77 0 : agent()->ConcurrencyCheck();
78 : DBTablePartition *tpart =
79 0 : static_cast<DBTablePartition *>(GetTablePartition(req.key.get()));
80 0 : Input(tpart, NULL, &req);
81 0 : }
82 :
83 91 : void CryptTunnelTable::CryptAvailability(const std::string &remote_ip,
84 : bool &crypt_traffic,
85 : bool &crypt_path_available) {
86 91 : crypt_traffic = false;
87 91 : crypt_path_available = false;
88 91 : CryptTunnelEntry *entry = Find(remote_ip);
89 91 : if (entry) {
90 0 : crypt_traffic = entry->GetVRToVRCrypt();
91 0 : crypt_path_available = entry->GetTunnelAvailable();
92 : }
93 91 : }
94 :
95 0 : bool CryptTunnelTable::IsCryptPathAvailable(const std::string &remote_ip) {
96 0 : bool ret = false;
97 0 : CryptTunnelEntry *entry = Find(remote_ip);
98 0 : if (entry && entry->GetTunnelAvailable())
99 0 : ret = true;
100 0 : return ret;
101 : }
102 :
103 0 : bool CryptTunnelTable::IsCryptTraffic(const std::string &remote_ip) {
104 0 : bool ret = false;
105 0 : CryptTunnelEntry *entry = Find(remote_ip);
106 0 : if (entry && entry->GetVRToVRCrypt())
107 0 : ret = true;
108 0 : return ret;
109 : }
110 :
111 91 : CryptTunnelEntry *CryptTunnelTable::Find(const std::string &remote_ip) {
112 91 : boost::system::error_code ec;
113 91 : IpAddress ip = IpAddress::from_string(remote_ip, ec);
114 91 : if (ec) {
115 0 : return NULL;
116 : }
117 91 : CryptTunnelKey key(ip);
118 91 : return static_cast<CryptTunnelEntry *>(FindActiveEntry(&key));
119 91 : }
120 :
121 0 : void CryptTunnelTable::Delete(const std::string &remote_ip) {
122 0 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
123 0 : boost::system::error_code ec;
124 0 : IpAddress ip = IpAddress::from_string(remote_ip, ec);
125 0 : if (ec) {
126 0 : return;
127 : }
128 0 : req.key.reset(new CryptTunnelKey(ip));
129 0 : req.data.reset(NULL);
130 0 : Process(req);
131 0 : return;
132 0 : }
133 :
134 0 : void CryptTunnelTable::Create(const std::string &remote_ip, bool vr_to_vr_crypt) {
135 0 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
136 0 : boost::system::error_code ec;
137 0 : IpAddress ip = IpAddress::from_string(remote_ip, ec);
138 0 : if (ec) {
139 0 : return;
140 : }
141 0 : req.key.reset(new CryptTunnelKey(ip));
142 0 : req.data.reset(new CryptTunnelConfigData(vr_to_vr_crypt));
143 0 : Process(req);
144 0 : }
145 :
146 2 : DBTableBase *CryptTunnelTable::CreateTable(Agent *agent, DB *db, const std::string &name) {
147 2 : CryptTunnelTable *crypt_tunnel_table = new CryptTunnelTable(agent, db, name);
148 2 : (static_cast<DBTable *>(crypt_tunnel_table))->Init();
149 2 : crypt_tunnel_table_ = crypt_tunnel_table;
150 2 : return crypt_tunnel_table;
151 : };
152 :
153 91 : std::unique_ptr<DBEntry> CryptTunnelTable::AllocEntry(const DBRequestKey *k) const {
154 91 : const CryptTunnelKey *key = static_cast<const CryptTunnelKey *>(k);
155 91 : CryptTunnelEntry *e = new CryptTunnelEntry(key->remote_ip_);
156 91 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(e));
157 : }
158 :
159 0 : DBEntry *CryptTunnelTable::Add(const DBRequest *req) {
160 0 : const CryptTunnelKey *key = static_cast<const CryptTunnelKey *>(req->key.get());
161 0 : CryptTunnelEntry *crypt_tunnel_entry = new CryptTunnelEntry(key->remote_ip_);
162 0 : ChangeHandler(crypt_tunnel_entry, req);
163 0 : crypt_tunnel_entry->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::ADD);
164 0 : return crypt_tunnel_entry;
165 : }
166 :
167 0 : bool CryptTunnelTable::ChangeHandler(CryptTunnelEntry *entry, const DBRequest *req) {
168 0 : bool ret = false;
169 0 : CryptTunnelConfigData *cdata = dynamic_cast<CryptTunnelConfigData *>(req->data.get());
170 0 : if (cdata && cdata->vr_to_vr_crypt_ != entry->vr_to_vr_crypt_) {
171 0 : entry->vr_to_vr_crypt_ = cdata->vr_to_vr_crypt_;
172 0 : ret = true;
173 : }
174 0 : CryptTunnelAvailableData *tdata = dynamic_cast<CryptTunnelAvailableData *>(req->data.get());
175 0 : if (tdata && tdata->tunnel_available_ != entry->tunnel_available_) {
176 0 : entry->tunnel_available_ = tdata->tunnel_available_;
177 0 : ret = true;
178 : }
179 0 : if (!entry->tunnel_task_) {
180 0 : entry->StartCryptTunnel();
181 0 : ret = true;
182 : }
183 0 : boost::system::error_code ec;
184 0 : IpAddress source_ip = IpAddress::from_string(agent()->router_id().to_string(), ec);
185 0 : entry->source_ip_ = source_ip;
186 0 : return ret;
187 : }
188 :
189 0 : bool CryptTunnelTable::OnChange(DBEntry *entry, const DBRequest *req) {
190 : bool ret;
191 0 : CryptTunnelEntry *crypt_tunnel_entry = static_cast<CryptTunnelEntry *>(entry);
192 0 : ret = ChangeHandler(crypt_tunnel_entry, req);
193 0 : if (ret)
194 0 : crypt_tunnel_entry->ResyncNH();
195 0 : crypt_tunnel_entry->UpdateTunnelReference();
196 0 : crypt_tunnel_entry->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::CHANGE);
197 0 : return ret;
198 : }
199 :
200 0 : bool CryptTunnelTable::Resync(DBEntry *entry, const DBRequest *req) {
201 : bool ret;
202 0 : CryptTunnelEntry *crypt_tunnel_entry = static_cast<CryptTunnelEntry *>(entry);
203 0 : ret = ChangeHandler(crypt_tunnel_entry, req);
204 0 : if (ret)
205 0 : crypt_tunnel_entry->ResyncNH();
206 0 : crypt_tunnel_entry->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::RESYNC);
207 0 : return ret;
208 : }
209 :
210 0 : bool CryptTunnelTable::Delete(DBEntry *entry, const DBRequest *req) {
211 0 : CryptTunnelEntry *crypt_tunnel_entry = static_cast<CryptTunnelEntry *>(entry);
212 0 : crypt_tunnel_entry->StopCryptTunnel();
213 0 : crypt_tunnel_entry->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::DEL);
214 0 : return true;
215 : }
216 :
217 2 : CryptTunnelTable::CryptTunnelTable(Agent *agent, DB *db, const std::string &name) :
218 2 : AgentDBTable(db, name), vr_to_vr_crypt_(false), crypt_interface_(NULL),
219 2 : tunnel_event_queue_(agent->task_scheduler()->GetTaskId(kTaskCryptTunnel), 0,
220 2 : boost::bind(&CryptTunnelTable::TunnelEventProcess, this, _1)) {
221 2 : tunnel_event_queue_.set_name("CryptTunnel event queue");
222 2 : set_agent(agent);
223 2 : }
224 :
225 4 : CryptTunnelTable::~CryptTunnelTable() {
226 2 : tunnel_event_queue_.Shutdown();
227 4 : }
228 :
229 : /////////////////////////////////////////////////////////////////////////////
230 : // Introspect routines
231 : /////////////////////////////////////////////////////////////////////////////
232 0 : bool CryptTunnelEntry::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
233 0 : CryptTunnelResp *resp = static_cast<CryptTunnelResp *>(sresp);
234 0 : if (name.empty() ||
235 0 : name == remote_ip_.to_string()) {
236 0 : CryptTunnelSandeshData data;
237 0 : data.set_source(std::string());
238 0 : data.set_remote(remote_ip_.to_string());
239 0 : data.set_available(tunnel_available_);
240 0 : data.set_crypt(vr_to_vr_crypt_);
241 : std::vector<CryptTunnelSandeshData> &list =
242 0 : const_cast<std::vector<CryptTunnelSandeshData>&>(resp->get_crypt_tunnel_list());
243 0 : list.push_back(data);
244 0 : return true;
245 0 : }
246 0 : return false;
247 : }
248 :
249 0 : void CryptTunnelEntry::SendObjectLog(SandeshTraceBufferPtr buf,
250 : AgentLogEvent::type event) const {
251 0 : CryptTunnelObjectLogInfo info;
252 0 : string str;
253 0 : switch(event) {
254 0 : case AgentLogEvent::ADD:
255 0 : str.assign("Addition");
256 0 : break;
257 0 : case AgentLogEvent::DEL:
258 0 : str.assign("Deletion");
259 0 : break;
260 0 : case AgentLogEvent::CHANGE:
261 0 : str.assign("Modification");
262 0 : break;
263 0 : case AgentLogEvent::RESYNC:
264 0 : str.assign("Resync");
265 0 : break;
266 0 : default:
267 0 : str.assign("");
268 0 : break;
269 : }
270 0 : info.set_event(str);
271 0 : info.set_remote(remote_ip_.to_string());
272 0 : info.set_source(std::string());
273 0 : info.set_available(tunnel_available_);
274 0 : info.set_crypt(vr_to_vr_crypt_);
275 0 : CRYPT_TUNNEL_OBJECT_LOG_LOG("CryptTunnel", SandeshLevel::SYS_INFO, info);
276 0 : CRYPT_TUNNEL_TRACE_TRACE(buf, info);
277 0 : }
278 :
279 0 : void CryptTunnelReq::HandleRequest() const {
280 0 : AgentSandeshPtr sand(new AgentCryptTunnelSandesh(context(), get_remote()));
281 0 : sand->DoSandesh(sand);
282 0 : }
283 :
284 0 : AgentSandeshPtr CryptTunnelTable::GetAgentSandesh(const AgentSandeshArguments *args,
285 : const std::string &context) {
286 : return AgentSandeshPtr(new AgentCryptTunnelSandesh(context,
287 0 : args->GetString("remote")));
288 : }
289 :
290 :
291 :
292 0 : CryptTunnelEvent::CryptTunnelEvent(CryptTunnelTaskBase *task,
293 : CryptTunnelEntry *entry, EventType type,
294 0 : const std::string &message) :
295 0 : tunnel_task_(task), entry_(entry), type_(type), message_(message) {
296 0 : }
297 :
298 0 : CryptTunnelEvent::~CryptTunnelEvent() {
299 0 : }
300 :
301 :
302 : /////////////////////////////////////////////////////////////////////////////
303 : // Instance base class methods
304 : /////////////////////////////////////////////////////////////////////////////
305 0 : CryptTunnelTaskBase::CryptTunnelTaskBase(CryptTunnelEntry *entry) :
306 0 : entry_(NULL), active_(false), last_update_time_("-"), deleted_(false) {
307 0 : }
308 :
309 0 : CryptTunnelTaskBase::~CryptTunnelTaskBase() {
310 0 : entry_ = NULL;
311 0 : }
312 :
313 0 : void CryptTunnelTaskBase::UpdateTunnel(const CryptTunnelEntry *entry, bool available) const {
314 0 : DBRequest req;
315 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
316 0 : CryptTunnelKey *key = new CryptTunnelKey(*entry->GetRemoteIp());
317 0 : key->sub_op_ = AgentKey::RESYNC;
318 0 : req.key.reset(key);
319 0 : CryptTunnelTable *ctable = static_cast<CryptTunnelTable *>(entry->get_table());
320 0 : req.data.reset(new CryptTunnelAvailableData(available));
321 0 : ctable->Process(req);
322 0 : }
323 :
324 0 : void CryptTunnelTaskBase::set_tunnel_entry(CryptTunnelEntry *entry) {
325 0 : if (entry_ == entry) {
326 0 : UpdateTunnelTask();
327 0 : return;
328 : }
329 0 : entry_ = entry;
330 0 : CreateTunnelTask();
331 : }
332 :
333 0 : std::string CryptTunnelTaskBase::to_string() {
334 0 : std::string str("Instance for crypt tunnel ");
335 0 : str += entry_->ToString();
336 0 : return str;
337 0 : }
338 :
339 0 : void CryptTunnelTaskBase::OnRead(const std::string &data) {
340 : CryptTunnelEvent *event =
341 0 : new CryptTunnelEvent(this, entry_.get(),
342 : CryptTunnelEvent::MESSAGE_READ,
343 0 : data);
344 0 : static_cast<CryptTunnelTable *>(entry_->get_table())->TunnelEventEnqueue(event);
345 0 : }
346 :
347 0 : void CryptTunnelTaskBase::OnExit(const boost::system::error_code &ec) {
348 : CryptTunnelEvent *event =
349 0 : new CryptTunnelEvent(this, entry_.get(),
350 0 : CryptTunnelEvent::TASK_EXIT, "");
351 0 : static_cast<CryptTunnelTable *>(entry_->get_table())->TunnelEventEnqueue(event);
352 0 : }
353 :
354 0 : void CryptTunnelTaskBase::SetTunnelEntry(CryptTunnelEntry *entry) {
355 : CryptTunnelEvent *event =
356 : new CryptTunnelEvent(this, entry,
357 0 : CryptTunnelEvent::SET_TUNNEL_ENTRY, "");
358 0 : static_cast<CryptTunnelTable *>(entry_->get_table())->TunnelEventEnqueue(event);
359 0 : }
360 :
361 0 : void CryptTunnelTaskBase::StopTask(CryptTunnelEntry *entry) {
362 : CryptTunnelEvent *event =
363 : new CryptTunnelEvent(this, entry,
364 0 : CryptTunnelEvent::STOP_TASK, "");
365 0 : static_cast<CryptTunnelTable *>(entry_->get_table())->TunnelEventEnqueue(event);
366 0 : }
367 :
368 :
369 : ////////////////////////////////////////////////////////////////////////////////
370 :
371 0 : CryptTunnelTask::CryptTunnelTask(CryptTunnelEntry *entry) :
372 : CryptTunnelTaskBase(entry),
373 0 : task_(NULL) {
374 0 : }
375 :
376 0 : CryptTunnelTask::~CryptTunnelTask() {
377 0 : }
378 :
379 0 : bool CryptTunnelTask::CreateTunnelTask() {
380 0 : if (!deleted_ && task_.get() != NULL) {
381 0 : return false;
382 : }
383 :
384 0 : deleted_ = false;
385 :
386 0 : CRYPT_TUNNEL_TASK_TRACE(Trace, "Starting " + this->to_string());
387 :
388 0 : Agent *agent = static_cast<CryptTunnelTable *>(entry_->get_table())->agent();
389 0 : task_.reset(new CryptTunnelProcessTunnel("CryptTunnel", "", 0,
390 0 : agent->event_manager()));
391 0 : if (task_.get() != NULL) {
392 0 : task_->set_pipe_stdout(true);
393 0 : task_->set_on_data_cb(
394 : boost::bind(&CryptTunnelTaskBase::OnRead, this, _2));
395 0 : task_->set_on_exit_cb(
396 : boost::bind(&CryptTunnelTaskBase::OnExit, this, _2));
397 0 : return RunTunnelTask(CryptTunnelTaskBase::CREATE_TUNNEL);
398 : }
399 :
400 0 : return false;
401 : }
402 :
403 0 : bool CryptTunnelTask::DestroyTunnelTask() {
404 0 : if (deleted_) {
405 0 : return true;
406 : }
407 0 : if (task_.get() == NULL) {
408 0 : return false;
409 : }
410 :
411 0 : CRYPT_TUNNEL_TASK_TRACE(Trace, "Deleting " + this->to_string());
412 0 : deleted_ = true;
413 0 : active_ = false;
414 : //StopTunnelTask();
415 0 : RunTunnelTask(CryptTunnelTaskBase::DELETE_TUNNEL);
416 0 : return true;
417 : }
418 :
419 0 : bool CryptTunnelTask::RunTunnelTask(CommandType cmd_type) {
420 0 : UpdateTunnelTaskCommand(cmd_type);
421 0 : return task_->Run();
422 : }
423 :
424 0 : bool CryptTunnelTask::StopTunnelTask() {
425 0 : task_->Stop();
426 0 : return true;
427 : }
428 :
429 0 : void CryptTunnelTask::UpdateTunnelTaskCommand(CommandType cmd_type) {
430 0 : Agent *agent = static_cast<CryptTunnelTable *>(entry_->get_table())->agent();
431 0 : if (agent->test_mode()) {
432 : // in test mode, set task instance to run no-op shell
433 0 : task_->set_cmd("echo success");
434 0 : return;
435 : }
436 0 : std::stringstream cmd_str;
437 0 : cmd_str << kCryptTunnelCmd;
438 0 : switch (cmd_type) {
439 0 : case CryptTunnelTaskBase::CREATE_TUNNEL:
440 : {
441 0 : cmd_str << " --oper create ";
442 : }
443 0 : break;
444 0 : case CryptTunnelTaskBase::UPDATE_TUNNEL:
445 : {
446 0 : cmd_str << " --oper update ";
447 : }
448 0 : break;
449 0 : case CryptTunnelTaskBase::MONITOR_TUNNEL:
450 : {
451 0 : cmd_str << " --oper status ";
452 : }
453 0 : break;
454 0 : case CryptTunnelTaskBase::DELETE_TUNNEL:
455 : {
456 0 : cmd_str << " --oper delete ";
457 : }
458 0 : break;
459 0 : default:
460 : // not supported
461 0 : assert(0);
462 : }
463 0 : cmd_str << " --source_ip " << entry_->GetSourceIp()->to_string();
464 0 : cmd_str << " --remote_ip " << entry_->GetRemoteIp()->to_string();
465 0 : task_->set_cmd(cmd_str.str());
466 0 : }
467 :
468 0 : bool CryptTunnelTask::IsRunning() const {
469 0 : return (task_.get() != NULL ? task_->is_running(): false);
470 : }
471 :
472 : ////////////////////////////////////////////////////////////////////////////////
473 :
474 0 : void CryptTunnelEntry::UpdateTunnelReference() {
475 0 : if (tunnel_task_)
476 0 : tunnel_task_->set_tunnel_entry(this);
477 0 : }
478 :
479 0 : CryptTunnelTaskBase *CryptTunnelEntry::StartCryptTunnel() {
480 0 : if (!tunnel_task_) {
481 0 : tunnel_task_ = new CryptTunnelTask(this);
482 : }
483 0 : return tunnel_task_;
484 : }
485 :
486 0 : void CryptTunnelEntry::StopCryptTunnel() {
487 0 : if (!tunnel_task_->DestroyTunnelTask()) {
488 0 : delete tunnel_task_;
489 0 : tunnel_task_ = NULL;
490 : }
491 0 : tunnel_available_ = false;
492 0 : vr_to_vr_crypt_ = false;
493 0 : ResyncNH();
494 0 : }
495 :
496 : void
497 0 : CryptTunnelTable::TunnelEventEnqueue(CryptTunnelEvent *event) {
498 0 : tunnel_event_queue_.Enqueue(event);
499 0 : }
500 :
501 0 : bool CryptTunnelTable::TunnelEventProcess(CryptTunnelEvent *event) {
502 0 : CryptTunnelTaskBase *tunnel_task = event->tunnel_task_;
503 0 : switch (event->type_) {
504 0 : case CryptTunnelEvent::MESSAGE_READ:
505 : {
506 0 : if (tunnel_task->deleted_)
507 0 : break;
508 0 : tunnel_task->last_update_time_ = UTCUsecToString(UTCTimestampUsec());
509 0 : std::string msg = event->message_;
510 0 : boost::algorithm::to_lower(msg);
511 0 : if (msg.find("success") != std::string::npos) {
512 0 : if (!tunnel_task->active_) {
513 0 : tunnel_task->active_ = true;
514 0 : tunnel_task->UpdateTunnel(tunnel_task->entry_.get(), true);
515 : }
516 : }
517 0 : if (msg.find("failure") != std::string::npos) {
518 0 : if (tunnel_task->active_) {
519 0 : tunnel_task->active_ = false;
520 0 : tunnel_task->UpdateTunnel(tunnel_task->entry_.get(), false);
521 : }
522 : }
523 : //CRYPT_TUNNEL_TASK_TRACE(Trace, tunnel_task->to_string() +
524 : // " Received msg = " + event->message_);
525 0 : }
526 0 : break;
527 :
528 0 : case CryptTunnelEvent::TASK_EXIT:
529 0 : if (tunnel_task->deleted_) {
530 0 : CRYPT_TUNNEL_TASK_TRACE(Trace, "Exit Deleted " + tunnel_task->to_string());
531 0 : delete tunnel_task;
532 : } else {
533 0 : tunnel_task->RunTunnelTask(CryptTunnelTaskBase::MONITOR_TUNNEL);
534 : }
535 0 : break;
536 :
537 0 : case CryptTunnelEvent::SET_TUNNEL_ENTRY:
538 0 : tunnel_task->set_tunnel_entry(event->entry_);
539 0 : break;
540 :
541 0 : case CryptTunnelEvent::STOP_TASK:
542 0 : if (!tunnel_task->DestroyTunnelTask()) {
543 0 : CRYPT_TUNNEL_TASK_TRACE(Trace, "Stopped " + tunnel_task->to_string());
544 0 : delete tunnel_task;
545 : }
546 0 : break;
547 :
548 0 : default:
549 : // unhandled event
550 0 : assert(0);
551 : }
552 :
553 0 : delete event;
554 0 : return true;
555 : }
|