4 * @brief Implementation of receiver_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30 #include <network/socket.h>
31 #include <network/packet.h>
32 #include <queues/job_queue.h>
33 #include <queues/jobs/job.h>
34 #include <queues/jobs/incoming_packet_job.h>
36 typedef struct block_t block_t
;
39 * entry for a blocked IP
49 * lifetime for this block
57 static void block_destroy(block_t
*block
)
59 block
->ip
->destroy(block
->ip
);
63 typedef struct private_receiver_t private_receiver_t
;
66 * Private data of a receiver_t object.
68 struct private_receiver_t
{
70 * Public part of a receiver_t object.
77 pthread_t assigned_thread
;
82 linked_list_t
*blocks
;
85 * mutex to exclusively access block list
87 pthread_mutex_t mutex
;
91 * Implementation of receiver_t.receive_packets.
93 static void receive_packets(private_receiver_t
* this)
98 /* cancellation disabled by default */
99 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
100 DBG1(DBG_NET
, "receiver thread running, thread_ID: %06u",
101 (int)pthread_self());
105 if (charon
->socket
->receive(charon
->socket
, &packet
) != SUCCESS
)
107 DBG1(DBG_NET
, "receiving from socket failed!");
111 if (this->blocks
->get_count(this->blocks
))
113 iterator_t
*iterator
;
116 u_int32_t now
= time(NULL
);
118 pthread_mutex_lock(&this->mutex
);
119 iterator
= this->blocks
->create_iterator(this->blocks
, TRUE
);
120 while (iterator
->iterate(iterator
, (void**)&blocked
))
122 if (now
> blocked
->timeout
)
124 /* block expired, remove */
125 iterator
->remove(iterator
);
126 block_destroy(blocked
);
130 if (!blocked
->ip
->ip_equals(blocked
->ip
,
131 packet
->get_source(packet
)))
133 /* no match, get next */
138 DBG2(DBG_NET
, "received packets source address %H blocked",
140 packet
->destroy(packet
);
144 iterator
->destroy(iterator
);
145 pthread_mutex_unlock(&this->mutex
);
148 /* get next packet */
153 DBG2(DBG_NET
, "creating job from packet");
154 job
= (job_t
*) incoming_packet_job_create(packet
);
155 charon
->job_queue
->add(charon
->job_queue
, job
);
160 * Implementation of receiver_t.block
162 static void block(private_receiver_t
*this, host_t
*ip
, u_int32_t seconds
)
164 block_t
*blocked
= malloc_thing(block_t
);
166 blocked
->ip
= ip
->clone(ip
);
167 blocked
->timeout
= time(NULL
) + seconds
;
168 DBG1(DBG_NET
, "blocking %H for %ds", ip
, seconds
);
170 pthread_mutex_lock(&this->mutex
);
171 this->blocks
->insert_last(this->blocks
, blocked
);
172 pthread_mutex_unlock(&this->mutex
);
176 * Implementation of receiver_t.destroy.
178 static void destroy(private_receiver_t
*this)
180 pthread_cancel(this->assigned_thread
);
181 pthread_join(this->assigned_thread
, NULL
);
182 this->blocks
->destroy_function(this->blocks
, (void*)block_destroy
);
187 * Described in header.
189 receiver_t
*receiver_create()
191 private_receiver_t
*this = malloc_thing(private_receiver_t
);
193 this->public.block
= (void(*)(receiver_t
*,host_t
*,u_int32_t
)) block
;
194 this->public.destroy
= (void(*)(receiver_t
*)) destroy
;
196 if (pthread_create(&(this->assigned_thread
), NULL
, (void*(*)(void*))receive_packets
, this) != 0)
199 charon
->kill(charon
, "unable to create receiver thread");
202 pthread_mutex_init(&this->mutex
, NULL
);
203 this->blocks
= linked_list_create();
205 return &(this->public);