Return to duplicheck_notify.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / duplicheck |
1.1 misho 1: /* 2: * Copyright (C) 2011 Martin Willi 3: * Copyright (C) 2011 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 "duplicheck_notify.h" 17: #include "duplicheck_msg.h" 18: 19: #include <sys/types.h> 20: #include <sys/stat.h> 21: #include <sys/socket.h> 22: #include <sys/un.h> 23: #include <unistd.h> 24: #include <errno.h> 25: 26: #include <daemon.h> 27: #include <threading/mutex.h> 28: #include <threading/thread.h> 29: #include <collections/linked_list.h> 30: #include <processing/jobs/callback_job.h> 31: 32: 33: typedef struct private_duplicheck_notify_t private_duplicheck_notify_t; 34: 35: /** 36: * Private data of an duplicheck_notify_t object. 37: */ 38: struct private_duplicheck_notify_t { 39: 40: /** 41: * Public duplicheck_notify_t interface. 42: */ 43: duplicheck_notify_t public; 44: 45: /** 46: * Mutex to lock list 47: */ 48: mutex_t *mutex; 49: 50: /** 51: * List of connected clients, as stream_t 52: */ 53: linked_list_t *connected; 54: 55: /** 56: * stream service accepting connections 57: */ 58: stream_service_t *service; 59: }; 60: 61: /** 62: * Accept duplicheck notification connections 63: */ 64: static bool on_accept(private_duplicheck_notify_t *this, stream_t *stream) 65: { 66: this->mutex->lock(this->mutex); 67: this->connected->insert_last(this->connected, stream); 68: this->mutex->unlock(this->mutex); 69: 70: return TRUE; 71: } 72: 73: METHOD(duplicheck_notify_t, send_, void, 74: private_duplicheck_notify_t *this, identification_t *id) 75: { 76: enumerator_t *enumerator; 77: stream_t *stream; 78: uint16_t nlen; 79: char buf[512]; 80: int len; 81: 82: len = snprintf(buf, sizeof(buf), "%Y", id); 83: if (len > 0 && len < sizeof(buf)) 84: { 85: nlen = htons(len); 86: 87: this->mutex->lock(this->mutex); 88: enumerator = this->connected->create_enumerator(this->connected); 89: while (enumerator->enumerate(enumerator, &stream)) 90: { 91: if (!stream->write_all(stream, &nlen, sizeof(nlen)) || 92: !stream->write_all(stream, buf, len)) 93: { 94: DBG1(DBG_CFG, "sending duplicheck notify failed: %s", 95: strerror(errno)); 96: this->connected->remove_at(this->connected, enumerator); 97: stream->destroy(stream); 98: } 99: } 100: enumerator->destroy(enumerator); 101: this->mutex->unlock(this->mutex); 102: } 103: } 104: 105: METHOD(duplicheck_notify_t, destroy, void, 106: private_duplicheck_notify_t *this) 107: { 108: DESTROY_IF(this->service); 109: this->connected->destroy_offset(this->connected, offsetof(stream_t, destroy)); 110: this->mutex->destroy(this->mutex); 111: free(this); 112: } 113: 114: /** 115: * See header 116: */ 117: duplicheck_notify_t *duplicheck_notify_create() 118: { 119: private_duplicheck_notify_t *this; 120: char *uri; 121: 122: INIT(this, 123: .public = { 124: .send = _send_, 125: .destroy = _destroy, 126: }, 127: .connected = linked_list_create(), 128: .mutex = mutex_create(MUTEX_TYPE_DEFAULT), 129: ); 130: 131: uri = lib->settings->get_str(lib->settings, 132: "%s.plugins.duplicheck.socket", "unix://" DUPLICHECK_SOCKET, 133: lib->ns); 134: this->service = lib->streams->create_service(lib->streams, uri, 3); 135: if (!this->service) 136: { 137: DBG1(DBG_CFG, "creating duplicheck socket failed"); 138: destroy(this); 139: return NULL; 140: } 141: this->service->on_accept(this->service, (stream_service_cb_t)on_accept, 142: this, JOB_PRIO_CRITICAL, 1); 143: 144: return &this->public; 145: }