]>
Commit | Line | Data |
---|---|---|
38831507 MW |
1 | /* |
2 | * Copyright (C) 2011 Martin Willi | |
19ef2aec TB |
3 | * |
4 | * Copyright (C) secunet Security Networks AG | |
38831507 MW |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2 of the License, or (at your | |
9 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | * for more details. | |
15 | */ | |
16 | ||
17 | #include "duplicheck_notify.h" | |
83faec5a | 18 | #include "duplicheck_msg.h" |
38831507 MW |
19 | |
20 | #include <sys/types.h> | |
21 | #include <sys/stat.h> | |
22 | #include <sys/socket.h> | |
23 | #include <sys/un.h> | |
24 | #include <unistd.h> | |
25 | #include <errno.h> | |
26 | ||
27 | #include <daemon.h> | |
28 | #include <threading/mutex.h> | |
29 | #include <threading/thread.h> | |
12642a68 | 30 | #include <collections/linked_list.h> |
38831507 MW |
31 | #include <processing/jobs/callback_job.h> |
32 | ||
38831507 MW |
33 | |
34 | typedef struct private_duplicheck_notify_t private_duplicheck_notify_t; | |
35 | ||
36 | /** | |
37 | * Private data of an duplicheck_notify_t object. | |
38 | */ | |
39 | struct private_duplicheck_notify_t { | |
40 | ||
41 | /** | |
42 | * Public duplicheck_notify_t interface. | |
43 | */ | |
44 | duplicheck_notify_t public; | |
45 | ||
38831507 MW |
46 | /** |
47 | * Mutex to lock list | |
48 | */ | |
49 | mutex_t *mutex; | |
50 | ||
51 | /** | |
83faec5a | 52 | * List of connected clients, as stream_t |
38831507 MW |
53 | */ |
54 | linked_list_t *connected; | |
55 | ||
56 | /** | |
83faec5a | 57 | * stream service accepting connections |
38831507 | 58 | */ |
83faec5a | 59 | stream_service_t *service; |
38831507 MW |
60 | }; |
61 | ||
38831507 MW |
62 | /** |
63 | * Accept duplicheck notification connections | |
64 | */ | |
83faec5a | 65 | static bool on_accept(private_duplicheck_notify_t *this, stream_t *stream) |
38831507 | 66 | { |
83faec5a MW |
67 | this->mutex->lock(this->mutex); |
68 | this->connected->insert_last(this->connected, stream); | |
69 | this->mutex->unlock(this->mutex); | |
38831507 | 70 | |
83faec5a | 71 | return TRUE; |
38831507 MW |
72 | } |
73 | ||
74 | METHOD(duplicheck_notify_t, send_, void, | |
75 | private_duplicheck_notify_t *this, identification_t *id) | |
76 | { | |
38831507 | 77 | enumerator_t *enumerator; |
83faec5a | 78 | stream_t *stream; |
b12c53ce | 79 | uint16_t nlen; |
83faec5a | 80 | char buf[512]; |
38831507 MW |
81 | int len; |
82 | ||
83 | len = snprintf(buf, sizeof(buf), "%Y", id); | |
84 | if (len > 0 && len < sizeof(buf)) | |
85 | { | |
83faec5a MW |
86 | nlen = htons(len); |
87 | ||
38831507 MW |
88 | this->mutex->lock(this->mutex); |
89 | enumerator = this->connected->create_enumerator(this->connected); | |
83faec5a | 90 | while (enumerator->enumerate(enumerator, &stream)) |
38831507 | 91 | { |
83faec5a MW |
92 | if (!stream->write_all(stream, &nlen, sizeof(nlen)) || |
93 | !stream->write_all(stream, buf, len)) | |
38831507 MW |
94 | { |
95 | DBG1(DBG_CFG, "sending duplicheck notify failed: %s", | |
96 | strerror(errno)); | |
97 | this->connected->remove_at(this->connected, enumerator); | |
83faec5a | 98 | stream->destroy(stream); |
38831507 MW |
99 | } |
100 | } | |
101 | enumerator->destroy(enumerator); | |
102 | this->mutex->unlock(this->mutex); | |
103 | } | |
104 | } | |
105 | ||
106 | METHOD(duplicheck_notify_t, destroy, void, | |
107 | private_duplicheck_notify_t *this) | |
108 | { | |
83faec5a MW |
109 | DESTROY_IF(this->service); |
110 | this->connected->destroy_offset(this->connected, offsetof(stream_t, destroy)); | |
38831507 MW |
111 | this->mutex->destroy(this->mutex); |
112 | free(this); | |
113 | } | |
114 | ||
115 | /** | |
116 | * See header | |
117 | */ | |
118 | duplicheck_notify_t *duplicheck_notify_create() | |
119 | { | |
120 | private_duplicheck_notify_t *this; | |
83faec5a | 121 | char *uri; |
38831507 MW |
122 | |
123 | INIT(this, | |
124 | .public = { | |
125 | .send = _send_, | |
126 | .destroy = _destroy, | |
127 | }, | |
128 | .connected = linked_list_create(), | |
129 | .mutex = mutex_create(MUTEX_TYPE_DEFAULT), | |
130 | ); | |
131 | ||
83faec5a MW |
132 | uri = lib->settings->get_str(lib->settings, |
133 | "%s.plugins.duplicheck.socket", "unix://" DUPLICHECK_SOCKET, | |
d223fe80 | 134 | lib->ns); |
83faec5a MW |
135 | this->service = lib->streams->create_service(lib->streams, uri, 3); |
136 | if (!this->service) | |
38831507 | 137 | { |
83faec5a | 138 | DBG1(DBG_CFG, "creating duplicheck socket failed"); |
38831507 MW |
139 | destroy(this); |
140 | return NULL; | |
141 | } | |
83faec5a MW |
142 | this->service->on_accept(this->service, (stream_service_cb_t)on_accept, |
143 | this, JOB_PRIO_CRITICAL, 1); | |
38831507 MW |
144 | |
145 | return &this->public; | |
146 | } |