Annotation of embedaddon/strongswan/src/libcharon/plugins/error_notify/error_notify_socket.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012 Martin Willi
3: * Copyright (C) 2012 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "error_notify_socket.h"
17:
18: #include <sys/types.h>
19: #include <sys/stat.h>
20: #include <sys/socket.h>
21: #include <sys/un.h>
22: #include <unistd.h>
23: #include <errno.h>
24:
25: #include <daemon.h>
26: #include <threading/thread.h>
27: #include <threading/mutex.h>
28: #include <collections/linked_list.h>
29: #include <processing/jobs/callback_job.h>
30:
31: #include "error_notify_msg.h"
32:
33: typedef struct private_error_notify_socket_t private_error_notify_socket_t;
34:
35: /**
36: * Private data of an error_notify_socket_t object.
37: */
38: struct private_error_notify_socket_t {
39:
40: /**
41: * Public error_notify_socket_t interface.
42: */
43: error_notify_socket_t public;
44:
45: /**
46: * Service accepting connections
47: */
48: stream_service_t *service;
49:
50: /**
51: * List of connected clients, as stream_t
52: */
53: linked_list_t *connected;
54:
55: /**
56: * Mutex to lock clients list
57: */
58: mutex_t *mutex;
59: };
60:
61: METHOD(error_notify_socket_t, has_listeners, bool,
62: private_error_notify_socket_t *this)
63: {
64: int count;
65:
66: this->mutex->lock(this->mutex);
67: count = this->connected->get_count(this->connected);
68: this->mutex->unlock(this->mutex);
69:
70: return count != 0;
71: }
72:
73: METHOD(error_notify_socket_t, notify, void,
74: private_error_notify_socket_t *this, error_notify_msg_t *msg)
75: {
76: enumerator_t *enumerator;
77: stream_t *stream;
78:
79: this->mutex->lock(this->mutex);
80: enumerator = this->connected->create_enumerator(this->connected);
81: while (enumerator->enumerate(enumerator, &stream))
82: {
83: if (!stream->write_all(stream, msg, sizeof(*msg)))
84: {
85: switch (errno)
86: {
87: case ECONNRESET:
88: case EPIPE:
89: /* disconnect, remove this listener */
90: this->connected->remove_at(this->connected, enumerator);
91: stream->destroy(stream);
92: break;
93: default:
94: DBG1(DBG_CFG, "sending notify failed: %s", strerror(errno));
95: break;
96: }
97: }
98: }
99: enumerator->destroy(enumerator);
100: this->mutex->unlock(this->mutex);
101: }
102:
103: /**
104: * Accept client connections
105: */
106: static bool on_accept(private_error_notify_socket_t *this, stream_t *stream)
107: {
108: this->mutex->lock(this->mutex);
109: this->connected->insert_last(this->connected, stream);
110: this->mutex->unlock(this->mutex);
111:
112: return TRUE;
113: }
114:
115: METHOD(error_notify_socket_t, destroy, void,
116: private_error_notify_socket_t *this)
117: {
118: DESTROY_IF(this->service);
119: this->connected->destroy_offset(this->connected, offsetof(stream_t, destroy));
120: this->mutex->destroy(this->mutex);
121: free(this);
122: }
123:
124: /**
125: * See header
126: */
127: error_notify_socket_t *error_notify_socket_create()
128: {
129: private_error_notify_socket_t *this;
130: char *uri;
131:
132: INIT(this,
133: .public = {
134: .notify = _notify,
135: .has_listeners = _has_listeners,
136: .destroy = _destroy,
137: },
138: .connected = linked_list_create(),
139: .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
140: );
141:
142: uri = lib->settings->get_str(lib->settings,
143: "%s.plugins.error-notify.socket", "unix://" ERROR_NOTIFY_SOCKET,
144: lib->ns);
145: this->service = lib->streams->create_service(lib->streams, uri, 10);
146: if (!this->service)
147: {
148: DBG1(DBG_CFG, "creating error-notify socket failed");
149: destroy(this);
150: return NULL;
151: }
152: this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
153: this, JOB_PRIO_CRITICAL, 1);
154:
155: return &this->public;
156: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>