ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/libopm/src/libopm.c
Revision: 8206
Committed: Sat Apr 15 21:54:36 2017 UTC (7 years ago) by michael
Content type: text/x-csrc
File size: 32399 byte(s)
Log Message:
- Rename functions in memory.c to be prefixed with libopm_

File Contents

# User Rev Content
1 michael 5052 /*
2     * Copyright (C) 2002-2003 Erik Fears
3     *
4     * This program is free software; you can redistribute it and/or
5     * modify it under the terms of the GNU General Public License
6     * as published by the Free Software Foundation; either version 2
7     * of the License, or (at your option) any later version.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to
16     *
17     * The Free Software Foundation, Inc.
18     * 59 Temple Place - Suite 330
19     * Boston, MA 02111-1307, USA.
20     *
21 michael 5909 *
22 michael 5052 */
23    
24     #include "setup.h"
25    
26 michael 8202 #include <errno.h>
27     #include <time.h>
28     #include <unistd.h>
29     #include <fcntl.h>
30     #include <string.h>
31     #include <stdlib.h>
32     #include <poll.h>
33     #ifdef HAVE_LIBCRYPTO
34     #include <openssl/ssl.h>
35     #endif
36    
37 michael 5052 #include "config.h"
38     #include "libopm.h"
39 michael 5947 #include "memory.h"
40 michael 5052 #include "opm_error.h"
41     #include "opm_types.h"
42     #include "opm_common.h"
43     #include "list.h"
44     #include "proxy.h"
45    
46    
47     static OPM_PROTOCOL_CONFIG_T *libopm_protocol_config_create(void);
48     static void libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *);
49    
50     static OPM_SCAN_T *libopm_scan_create(OPM_T *, OPM_REMOTE_T *);
51     static void libopm_scan_free(OPM_SCAN_T *);
52    
53     static OPM_CONNECTION_T *libopm_connection_create(void);
54     static void libopm_connection_free(OPM_CONNECTION_T *);
55    
56     static void libopm_check_establish(OPM_T *);
57     static void libopm_check_poll(OPM_T *);
58     static void libopm_check_closed(OPM_T *);
59     static void libopm_check_queue(OPM_T *);
60    
61     static void libopm_do_connect(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
62     static void libopm_do_readready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
63 michael 6222 static int libopm_do_readready_tls(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
64 michael 5052 static void libopm_do_writeready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
65     static void libopm_do_hup(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
66     static void libopm_do_read(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
67     static void libopm_do_openproxy(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
68     static void libopm_do_callback(OPM_T *, OPM_REMOTE_T *, int, int);
69    
70     static OPM_REMOTE_T *libopm_setup_remote(OPM_REMOTE_T *, OPM_CONNECTION_T *);
71    
72    
73     /* OPM_PROTOCOLS hash
74     *
75     * OPM_PPROTOCOLS hashes the protocol types (int) to functions
76     * which handle the protocol (sending/receiving protocol specific
77     * data).
78     *
79     */
80 michael 5325 static OPM_PROTOCOL_T OPM_PROTOCOLS[] =
81     {
82 michael 6222 { OPM_TYPE_HTTP, libopm_proxy_http_write, NULL, 0 },
83     { OPM_TYPE_SOCKS4, libopm_proxy_socks4_write, NULL, 0 },
84     { OPM_TYPE_SOCKS5, libopm_proxy_socks5_write, NULL, 0 },
85     { OPM_TYPE_ROUTER, libopm_proxy_router_write, NULL, 0 },
86     { OPM_TYPE_WINGATE, libopm_proxy_wingate_write, NULL, 0 },
87     { OPM_TYPE_HTTPPOST, libopm_proxy_httppost_write, NULL, 0 },
88     { OPM_TYPE_DREAMBOX, libopm_proxy_dreambox_write, NULL, 0 },
89     { OPM_TYPE_HTTPS, libopm_proxy_https_write, libopm_do_readready_tls, 1 },
90     { OPM_TYPE_HTTPSPOST, libopm_proxy_httpspost_write, libopm_do_readready_tls, 1 }
91 michael 5052 };
92    
93     /* opm_create
94     *
95     * Initialize a new scanner and return a pointer to it.
96     *
97     * Parameters:
98     * None
99 michael 5325 *
100     * Return
101 michael 5052 * Pointer to new OPM_T (scanner)
102     */
103 michael 5325 OPM_T *
104     opm_create(void)
105 michael 5052 {
106 michael 5325 OPM_T *ret;
107 michael 5052
108 michael 8206 ret = libopm_calloc(sizeof(*ret));
109 michael 5325 ret->config = libopm_config_create();
110     ret->scans = libopm_list_create();
111     ret->queue = libopm_list_create();
112     ret->protocols = libopm_list_create();
113 michael 5052
114 michael 5325 /* Setup callbacks */
115 michael 8206 ret->callbacks = libopm_calloc(sizeof(OPM_CALLBACK_T) * CBLEN);
116 michael 5052
117 michael 5325 return ret;
118 michael 5052 }
119    
120     /* opm_remote_create
121     *
122     * Create OPM_REMOTE_T struct, fill it with neccessary
123     * default values and return it to the client.
124     *
125     * Parameters:
126     * ip: IP of remote host
127     *
128     * Return:
129     * Address of OPM_REMOTE_T created
130     *
131     */
132 michael 5325 OPM_REMOTE_T *
133     opm_remote_create(const char *ip)
134     {
135     OPM_REMOTE_T *ret;
136 michael 5052
137 michael 8206 ret = libopm_calloc(sizeof(*ret));
138     ret->ip = libopm_strdup(ip);
139 michael 5325 ret->protocols = libopm_list_create(); /* Setup protocol list */
140 michael 5094
141 michael 5325 return ret;
142 michael 5052 }
143    
144     /* opm_remote_free
145     *
146     * Free OPM_REMOTE_T struct and cleanup
147     *
148     * Parameters:
149     * remote: Struct to free
150     *
151     * Return:
152     * None
153     */
154 michael 5325 void
155     opm_remote_free(OPM_REMOTE_T *remote)
156 michael 5052 {
157 michael 5325 OPM_NODE_T *p, *next;
158     OPM_PROTOCOL_CONFIG_T *ppc;
159 michael 5052
160 michael 8206 libopm_free(remote->ip);
161 michael 5052
162 michael 5325 LIST_FOREACH_SAFE(p, next, remote->protocols->head)
163     {
164     ppc = p->data;
165 michael 5052
166 michael 5325 libopm_protocol_config_free(ppc);
167     libopm_list_remove(remote->protocols, p);
168     libopm_node_free(p);
169     }
170 michael 5052
171 michael 5325 libopm_list_free(remote->protocols);
172 michael 5052
173 michael 8206 libopm_free(remote);
174 michael 5052 }
175    
176     /* opm_callback
177     * Register scanner level callback
178     *
179     * Parameters
180     * scanner: scanner struct
181     * type: callback type
182     * Return:
183     * Error code
184     */
185    
186 michael 5325 OPM_ERR_T
187     opm_callback(OPM_T *scanner, int type, OPM_CALLBACK_FUNC *function, void *data)
188 michael 5052 {
189 michael 5673 if (type < 0 || type >= CBLEN)
190 michael 5325 return OPM_ERR_CBNOTFOUND;
191 michael 5052
192 michael 5325 scanner->callbacks[type].func = function;
193     scanner->callbacks[type].data = data;
194 michael 5052
195 michael 5325 return OPM_SUCCESS;
196 michael 5052 }
197    
198     /* opm_free
199     *
200     * Free OPM_T (scanner) and cleanup
201     *
202     * Parameters:
203     * scanner: Address of OPM_T to cleanup
204     *
205     * Return:
206     * None
207     */
208 michael 5325 void
209     opm_free(OPM_T *scanner)
210 michael 5052 {
211 michael 5325 OPM_NODE_T *p, *next;
212     OPM_PROTOCOL_CONFIG_T *ppc;
213     OPM_SCAN_T *scan;
214 michael 5052
215 michael 5325 libopm_config_free(scanner->config);
216 michael 5052
217 michael 5325 LIST_FOREACH_SAFE(p, next, scanner->protocols->head)
218     {
219     ppc = p->data;
220 michael 5052
221 michael 5325 libopm_protocol_config_free(ppc);
222     libopm_list_remove(scanner->protocols, p);
223     libopm_node_free(p);
224     }
225 michael 5052
226 michael 5325 LIST_FOREACH_SAFE(p, next, scanner->scans->head)
227     {
228     scan = p->data;
229 michael 5052
230 michael 5325 libopm_scan_free(scan);
231     libopm_list_remove(scanner->scans, p);
232     libopm_node_free(p);
233     }
234 michael 5052
235 michael 5325 LIST_FOREACH_SAFE(p, next, scanner->queue->head)
236     {
237     scan = p->data;
238 michael 5052
239 michael 5325 libopm_scan_free(scan);
240     libopm_list_remove(scanner->queue, p);
241     libopm_node_free(p);
242     }
243 michael 5052
244 michael 5325 libopm_list_free(scanner->protocols);
245     libopm_list_free(scanner->scans);
246     libopm_list_free(scanner->queue);
247 michael 5052
248 michael 8206 libopm_free(scanner->callbacks);
249     libopm_free(scanner);
250 michael 5325 }
251 michael 5052
252     /* opm_config
253     *
254     * Wrapper to config_set. Set configuration variables
255     * on the config struct.
256     *
257     * Parameters:
258     * scanner: OPM_T struct the config struct resides in
259     * key: Variable within the config struct to set
260     * value: Address of value to set variable (key) to
261     *
262     * Return:
263     * OPM_ERR_T containing error code
264     */
265 michael 5325 OPM_ERR_T
266     opm_config(OPM_T *scanner, int key, const void *value)
267 michael 5052 {
268 michael 6076 return libopm_config_set(scanner->config, key, value);
269 michael 5052 }
270    
271     /* opm_addtype
272     *
273 michael 5325 * Add a proxy type and port to the list of protocols
274 michael 5052 * a scanner will use.
275 michael 5325 *
276 michael 5052 * Parameters:
277     * scanner: pointer to scanner struct
278     * type: type of proxy to scan (used in hashing to the functions)
279     * port: port this specific type/protocol will scan on
280     * Return:
281     * OPM_SUCCESS: Successful protocol add
282     * OPM_ERR_BADPROTOCOL: Protocol is unknown
283     */
284 michael 5325 OPM_ERR_T
285     opm_addtype(OPM_T *scanner, int type, unsigned short int port)
286 michael 5052 {
287 michael 5325 OPM_NODE_T *node;
288     OPM_PROTOCOL_CONFIG_T *protocol_config;
289 michael 5052
290 michael 5671 for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i)
291 michael 5325 {
292     if (type == OPM_PROTOCOLS[i].type)
293     {
294 michael 6222 #ifndef HAVE_LIBCRYPTO
295     if (OPM_PROTOCOLS[i].use_tls)
296     return OPM_ERR_BADPROTOCOL;
297     #endif
298 michael 5325 protocol_config = libopm_protocol_config_create();
299     protocol_config->type = &OPM_PROTOCOLS[i];
300     protocol_config->port = port;
301 michael 5052
302 michael 5325 node = libopm_node_create(protocol_config);
303     libopm_list_add(scanner->protocols, node);
304 michael 5052
305 michael 5325 return OPM_SUCCESS;
306     }
307     }
308 michael 5052
309 michael 5325 return OPM_ERR_BADPROTOCOL;
310 michael 5052 }
311    
312     /* opm_remote_addtype
313     *
314     * Add a proxy type and port to the list of protocols
315     * a scanner will use.
316     *
317     * Parameters:
318     * remote: pointer to scanner struct
319     * type: type of proxy to scan (used in hashing to the functions)
320     * port: port this specific type/protocol will scan on
321     * Return:
322     * OPM_SUCCESS: Successful protocol add
323     * OPM_ERR_BADPROTOCOL: Protocol is unknown
324     */
325     OPM_ERR_T opm_remote_addtype(OPM_REMOTE_T *remote, int type, unsigned short int port)
326     {
327 michael 5325 OPM_NODE_T *node;
328     OPM_PROTOCOL_CONFIG_T *protocol_config;
329 michael 5052
330 michael 5671 for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i)
331 michael 5325 {
332     if (type == OPM_PROTOCOLS[i].type)
333     {
334 michael 6222 #ifndef HAVE_LIBCRYPTO
335     if (OPM_PROTOCOLS[i].use_tls)
336     return OPM_ERR_BADPROTOCOL;
337     #endif
338 michael 5325 protocol_config = libopm_protocol_config_create();
339     protocol_config->type = &OPM_PROTOCOLS[i];
340     protocol_config->port = port;
341 michael 5052
342 michael 5325 node = libopm_node_create(protocol_config);
343     libopm_list_add(remote->protocols, node);
344 michael 5052
345 michael 5325 return OPM_SUCCESS;
346     }
347     }
348 michael 5052
349 michael 5325 return OPM_ERR_BADPROTOCOL;
350 michael 5052 }
351    
352     /* libopm_protocol_config_create
353     *
354     * Allocate and return address of a new OPM_PROTOCOL_CONFIG_T
355     *
356     * Parameters:
357     * None
358     *
359     * Return:
360     * Address of new OPM_PROTOCOL_CONFIG_T
361     */
362 michael 5325 static OPM_PROTOCOL_CONFIG_T *
363     libopm_protocol_config_create(void)
364 michael 5052 {
365 michael 5325 OPM_PROTOCOL_CONFIG_T *ret;
366 michael 5671
367 michael 8206 ret = libopm_calloc(sizeof(*ret));
368 michael 5052
369 michael 5325 return ret;
370 michael 5052 }
371    
372     /* protocol_config_free
373     *
374     * Free OPM_PROTOCOL_CONFIG_T struct
375     *
376     * Parameters:
377     * protocol: struct to free
378     *
379     * Return:
380     * None
381     */
382 michael 5325 static void
383     libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *protocol)
384 michael 5052 {
385 michael 8206 libopm_free(protocol);
386 michael 5052 }
387    
388     /* opm_scan
389     *
390     * Scan remote host. The opm_scan function takes an OPM_REMOTE_T
391     * struct, calculates the in_addr of the remote host, and creates
392     * a scan list based on protocols defined in the scanner.
393     *
394     * Parameters:
395     * scanner: Scanner to scan host on
396     * remote: OPM_REMOTE_T defining remote host
397 michael 5325 *
398 michael 5052 * Return:
399     * (to be written)
400     */
401 michael 5325 OPM_ERR_T
402     opm_scan(OPM_T *scanner, OPM_REMOTE_T *remote)
403 michael 5052 {
404 michael 5325 OPM_SCAN_T *scan; /* New scan for OPM_T */
405     OPM_NODE_T *node; /* Node we'll add scan to when we link it to scans */
406 michael 8131 struct in_addr in;
407 michael 5052
408 michael 5325 if (LIST_SIZE(scanner->protocols) == 0 &&
409 michael 5052 LIST_SIZE(remote->protocols) == 0)
410 michael 5325 return OPM_ERR_NOPROTOCOLS;
411 michael 5052
412 michael 8127 /*
413     * XXX: libopm ideally shouldn't see an IP address in string representation.
414     * Could have been stuffed into the _OPM_REMOTE struct by the caller that
415     * already does getaddrinfo() anyway.
416     */
417 michael 8131 if (inet_pton(AF_INET, remote->ip, &in) <= 0)
418 michael 8127 return OPM_ERR_BADADDR;
419    
420 michael 5325 scan = libopm_scan_create(scanner, remote);
421 michael 8131 memcpy(&scan->addr.sin_addr, &in, sizeof(scan->addr.sin_addr));
422 michael 5052
423 michael 5325 node = libopm_node_create(scan);
424     libopm_list_add(scanner->queue, node);
425 michael 5052
426 michael 5325 return OPM_SUCCESS;
427 michael 5052 }
428    
429     /* opm_end
430     *
431     * End a scan prematurely.
432     *
433     * Parameters:
434     * scanner: Scanner to end scan on
435     * remote: Pointer to remote struct to search for and end
436     *
437 michael 5325 * Return:
438 michael 5052 * No return. OPM_CALLBACK_END will still be called as normal.
439     */
440 michael 5325 void
441     opm_end(OPM_T *scanner, OPM_REMOTE_T *remote)
442 michael 5052 {
443 michael 5325 OPM_NODE_T *node1, *node2, *next1, *next2;
444     OPM_SCAN_T *scan;
445     OPM_CONNECTION_T *conn;
446 michael 5052
447 michael 5325 /* End active scans */
448     opm_endscan(scanner, remote);
449 michael 5052
450 michael 5325 /*
451     * Secondly remove all traces of it in the queue. Once removed we have to call
452     * OPM_CALLBACK_END
453     */
454     LIST_FOREACH_SAFE(node1, next1, scanner->queue->head)
455     {
456     scan = node1->data;
457 michael 5052
458 michael 5325 if (scan->remote == remote)
459     {
460     /* Free all connections */
461     LIST_FOREACH_SAFE(node2, next2, scan->connections->head)
462 michael 5052 {
463 michael 5325 conn = node2->data;
464 michael 5052
465 michael 5325 libopm_list_remove(scan->connections, node2);
466     libopm_connection_free(conn);
467     libopm_node_free(node2);
468     continue;
469     }
470 michael 5052
471 michael 5325 /* OPM_CALLBACK_END because check_closed normally handles this */
472     libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
473 michael 5052
474 michael 5325 /* Free up the scan */
475     libopm_list_remove(scanner->queue, node1);
476     libopm_scan_free(scan);
477     libopm_node_free(node1);
478     }
479     }
480 michael 5052 }
481    
482     /* opm_endscan
483     *
484     * End a scan prematurely. Only end non-queued scans. This is useful
485     * because it only checks the active scan list (saving time), where
486     * opm_end checks both the scan and the possibly large queue.
487     *
488     * Parameters:
489     * scanner: Scanner to end scan on
490     * remote: Pointer to remote struct to search for and end
491     *
492     * Return:
493     * No return. OPM_CALLBACK_END will still be called as normal.
494     */
495 michael 5325 void
496     opm_endscan(OPM_T *scanner, OPM_REMOTE_T *remote)
497 michael 5052 {
498 michael 5325 OPM_NODE_T *node1, *node2;
499     OPM_SCAN_T *scan;
500     OPM_CONNECTION_T *conn;
501 michael 5052
502 michael 5325 /*
503     * First check to see if it's in the queue, if it is set all connections closed
504     * Next cycle of libopm_check_closed will take care of the garbage and handle
505     * OPM_CALLBACK_END
506 michael 5052 */
507 michael 5325 LIST_FOREACH(node1, scanner->scans->head)
508     {
509     scan = node1->data;
510 michael 5052
511 michael 5325 if (scan->remote == remote)
512     {
513     LIST_FOREACH(node2, scan->connections->head)
514 michael 5052 {
515 michael 5912 conn = node2->data;
516 michael 5325 conn->state = OPM_STATE_CLOSED;
517 michael 5052 }
518 michael 5325 }
519     }
520 michael 5052 }
521    
522 michael 5325 /* opm_active
523 michael 5052
524     Return number of scans in a scanner left.
525    
526     Parameters:
527     scanner: Scanner to return active scans on
528    
529     Return:
530     Number of active scans, both queued and active.
531     */
532 michael 5325 size_t
533     opm_active(OPM_T *scanner)
534 michael 5052 {
535 michael 5325 return LIST_SIZE(scanner->queue) + LIST_SIZE(scanner->scans);
536 michael 5052 }
537    
538     /* scan_create
539     *
540     * Create new OPM_SCAN_T struct
541     *
542 michael 5325 * Parameters:
543 michael 5052 * scanner: Scanner the scan is being created for. This
544     * is needed to get information on currently set
545     * protocols/config.
546 michael 5909 *
547 michael 5052 * remote: Remote host this scan will be scanning
548 michael 5909 *
549 michael 5052 * Return
550     * Address of new struct
551     */
552 michael 5325 static OPM_SCAN_T *
553     libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
554 michael 5052 {
555 michael 5325 OPM_SCAN_T *ret;
556     OPM_CONNECTION_T *conn;
557     OPM_NODE_T *node, *p;
558 michael 6222 #ifdef HAVE_LIBCRYPTO
559     static int tls_init = 0;
560     static SSL_CTX *ctx_client;
561 michael 5052
562 michael 6222 if (!tls_init)
563     {
564     tls_init = 1;
565     SSLeay_add_ssl_algorithms();
566    
567     ctx_client = SSL_CTX_new(SSLv23_client_method());
568     if (!ctx_client)
569     exit(EXIT_FAILURE);
570     }
571     #endif
572    
573 michael 8206 ret = libopm_calloc(sizeof(*ret));
574 michael 5325 ret->remote = remote;
575     ret->connections = libopm_list_create();
576 michael 5052
577 michael 5671 /* Setup list of connections, one for each protocol */
578 michael 5325 LIST_FOREACH(p, scanner->protocols->head)
579     {
580     conn = libopm_connection_create();
581 michael 5052
582 michael 5671 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
583     conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
584 michael 5052
585 michael 6222 #ifdef HAVE_LIBCRYPTO
586     if (conn->protocol->use_tls)
587     /* SSL_new does only fail if OOM in which case HOPM exits anyway */
588     conn->tls_handle = SSL_new(ctx_client);
589     #endif
590    
591 michael 5325 node = libopm_node_create(conn);
592     libopm_list_add(ret->connections, node);
593     }
594 michael 5052
595 michael 5325 /*
596     * Do the same for any specific protocols the remote struct might be configured with
597     */
598     LIST_FOREACH(p, remote->protocols->head)
599     {
600     conn = libopm_connection_create();
601 michael 5052
602 michael 5671 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
603     conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
604 michael 5052
605 michael 6222 #ifdef HAVE_LIBCRYPTO
606     if (conn->protocol->use_tls)
607     /* SSL_new does only fail if OOM in which case HOPM exits anyway */
608     conn->tls_handle = SSL_new(ctx_client);
609     #endif
610    
611 michael 5325 node = libopm_node_create(conn);
612     libopm_list_add(ret->connections, node);
613     }
614 michael 5052
615 michael 5325 return ret;
616 michael 5052 }
617    
618     /* scan_free
619     *
620     * Free and cleanup OPM_SCAN_T struct
621     *
622     * Parametsr:
623     * scan: Scan struct to free
624 michael 5909 *
625 michael 5052 * Return:
626     * None
627     */
628 michael 5325 static void
629     libopm_scan_free(OPM_SCAN_T *scan)
630 michael 5052 {
631 michael 5325 OPM_NODE_T *p, *next;
632     OPM_CONNECTION_T *conn;
633 michael 5052
634 michael 5325 LIST_FOREACH_SAFE(p, next, scan->connections->head)
635     {
636     conn = p->data;
637 michael 5052
638 michael 5325 libopm_connection_free(conn);
639     libopm_list_remove(scan->connections, p);
640     libopm_node_free(p);
641     }
642 michael 5052
643 michael 5325 libopm_list_free(scan->connections);
644    
645 michael 8206 libopm_free(scan);
646 michael 5052 }
647    
648     /* connection_create
649     *
650     * Allocate new OPM_CONNECTION_T
651     *
652     * Parameters:
653     * None
654     *
655     * Return:
656     * Address of new OPM_CONNECTION_T
657     */
658 michael 5325 static OPM_CONNECTION_T *
659     libopm_connection_create(void)
660 michael 5052 {
661 michael 5325 OPM_CONNECTION_T *ret;
662 michael 5052
663 michael 8206 ret = libopm_calloc(sizeof(*ret));
664 michael 5913 ret->state = OPM_STATE_UNESTABLISHED;
665 michael 5052
666 michael 5325 return ret;
667 michael 5052 }
668    
669     /* connection_free
670     *
671     * Free OPM_CONNECTION_T struct
672     *
673     * Parameters:
674     * conn: Address of struct to free
675     *
676     * Return:
677     * None
678     */
679 michael 5325 static void
680     libopm_connection_free(OPM_CONNECTION_T *conn)
681 michael 5052 {
682 michael 8206 libopm_free(conn);
683 michael 5052 }
684    
685     /* opm_cycle
686     *
687     * Perform tasks (called by client's loop)
688     *
689     * Parameters:
690     * None
691     * Return:
692     * None
693     */
694 michael 5325 void
695     opm_cycle(OPM_T *scanner)
696 michael 5052 {
697 michael 5325 libopm_check_queue(scanner); /* Move scans from the queue to the live scan list */
698     libopm_check_establish(scanner); /* Make new connections if possible */
699     libopm_check_poll(scanner); /* Poll connections for IO and proxy test */
700     libopm_check_closed(scanner); /* Check for closed or timed out connections */
701 michael 5052 }
702    
703     /* check_queue
704     *
705     * Move scans from the queue to the live scan list as long as there is
706     * room.
707     *
708 michael 5909 * Parameters:
709 michael 5052 * scanner: Scanner to check queue on
710     *
711     * Return:
712     * None
713     */
714 michael 5325 static void
715     libopm_check_queue(OPM_T *scanner)
716 michael 5052 {
717 michael 5671 OPM_NODE_T *node;
718     OPM_SCAN_T *scan;
719     unsigned int protocols, projected, fd_limit;
720 michael 5052
721 michael 5671 if (LIST_SIZE(scanner->queue) == 0)
722     return;
723 michael 5052
724 michael 5671 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
725     projected = scanner->fd_use;
726 michael 5052
727 michael 5671 /*
728     * We want to keep the live scan list as small as possible, so only move
729     * queued scans to the live list if they will not push above fd_limit
730     */
731     while (LIST_SIZE(scanner->queue) > 0)
732     {
733     /* Grab the top scan */
734     scan = scanner->queue->head->data;
735     protocols = LIST_SIZE(scan->connections);
736 michael 5052
737 michael 5671 /* Check if it will fit in the live scan list */
738     if ((protocols + projected) > fd_limit)
739     break;
740 michael 5052
741 michael 5671 /*
742     * Scans on the top of the queue were added first, swap the head off the
743     * top of the queue and add it to the tail of the live scan list
744     */
745     node = libopm_list_remove(scanner->queue, scanner->queue->head);
746     libopm_list_add(scanner->scans, node);
747     projected += protocols;
748     }
749 michael 5052 }
750    
751     /* check_establish
752     *
753     * Make new connections if there are free file descriptors and connections
754     * to be made.
755     *
756     * Parameters:
757     * scanner: Scanner to check for establish on
758     * Return:
759     * None
760     */
761 michael 5325 static void
762     libopm_check_establish(OPM_T *scanner)
763 michael 5052 {
764 michael 5325 OPM_NODE_T *node1, *node2;
765     OPM_SCAN_T *scan;
766     OPM_CONNECTION_T *conn;
767     unsigned int fd_limit;
768 michael 5052
769 michael 5325 if (LIST_SIZE(scanner->scans) == 0)
770     return;
771 michael 5052
772 michael 5325 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
773 michael 5052
774 michael 5325 if (scanner->fd_use >= fd_limit)
775     return;
776 michael 5052
777 michael 5325 LIST_FOREACH(node1, scanner->scans->head)
778     {
779     scan = node1->data;
780 michael 5052
781 michael 5325 LIST_FOREACH(node2, scan->connections->head)
782     {
783     /* Only scan if we have free file descriptors */
784     if (scanner->fd_use >= fd_limit)
785     return;
786 michael 5052
787 michael 5325 conn = node2->data;
788    
789     if (conn->state == OPM_STATE_UNESTABLISHED)
790     libopm_do_connect(scanner, scan, conn);
791 michael 5671 }
792 michael 5325 }
793 michael 5052 }
794    
795     /* check_closed
796 michael 5909 *
797 michael 5052 * Check for connections which have timed out or are
798     * closed. Connections timed out still need to be closed.
799     *
800     * Remove the connection from the list of connections, free
801     * the connection struct and free the list node. Then if this is
802     * the last connection of the scan, consider the scan completed and
803     * free the scan aswell (and callback that the scan ended).
804     *
805     * Parameters:
806     * scanner: Scanner to check on
807     * Return:
808     * None
809     */
810 michael 5325 static void
811     libopm_check_closed(OPM_T *scanner)
812 michael 5052 {
813 michael 5671 time_t present;
814     int timeout;
815     OPM_NODE_T *node1, *node2, *next1, *next2;
816     OPM_SCAN_T *scan;
817     OPM_CONNECTION_T *conn;
818 michael 5052
819 michael 5671 if (LIST_SIZE(scanner->scans) == 0)
820     return;
821 michael 5052
822 michael 5671 time(&present);
823     timeout = *(int *)libopm_config(scanner->config, OPM_CONFIG_TIMEOUT);
824 michael 5052
825 michael 5671 LIST_FOREACH_SAFE(node1, next1, scanner->scans->head)
826     {
827     scan = node1->data;
828 michael 5052
829 michael 5671 LIST_FOREACH_SAFE(node2, next2, scan->connections->head)
830     {
831     conn = node2->data;
832 michael 5052
833 michael 5671 if (conn->state == OPM_STATE_CLOSED)
834 michael 5052 {
835 michael 6222 #ifdef HAVE_LIBCRYPTO
836     if (conn->protocol->use_tls)
837     {
838     SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
839     if (!SSL_shutdown(conn->tls_handle))
840     SSL_shutdown(conn->tls_handle);
841     SSL_free(conn->tls_handle);
842     }
843     #endif
844 michael 6224 if (conn->fd > -1)
845 michael 5671 close(conn->fd);
846 michael 5052
847 michael 5671 scanner->fd_use--;
848 michael 5052
849 michael 5671 libopm_list_remove(scan->connections, node2);
850     libopm_connection_free(conn);
851     libopm_node_free(node2);
852     continue;
853 michael 5052 }
854    
855 michael 5671 if (((present - conn->creation) >= timeout) && conn->state != OPM_STATE_UNESTABLISHED)
856 michael 5052 {
857 michael 6222 #ifdef HAVE_LIBCRYPTO
858     if (conn->protocol->use_tls)
859     {
860     SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
861     if (!SSL_shutdown(conn->tls_handle))
862     SSL_shutdown(conn->tls_handle);
863     SSL_free(conn->tls_handle);
864     }
865     #endif
866 michael 6224 if (conn->fd > -1)
867     close(conn->fd);
868    
869 michael 5671 scanner->fd_use--;
870 michael 5052
871 michael 5671 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_TIMEOUT, 0);
872     libopm_list_remove(scan->connections, node2);
873     libopm_connection_free(conn);
874     libopm_node_free(node2);
875     continue;
876 michael 5052 }
877 michael 5671 }
878    
879     /*
880     * No more connections left in this scan, let the client know the scan has
881     * ended, then remove the scan from the scanner, and free it up.
882     */
883     if (LIST_SIZE(scan->connections) == 0)
884     {
885     libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
886     libopm_list_remove(scanner->scans, node1);
887     libopm_scan_free(scan);
888     libopm_node_free(node1);
889     }
890     }
891 michael 5052 }
892    
893     /* do_connect
894     *
895     * Call socket() and connect() to start a scan.
896     *
897     * Parametsr:
898     * scan: Scan struct containing the connection
899     * conn: Connection to establish
900 michael 5909 * Return:
901 michael 5052 * None
902     */
903 michael 5325 static void
904     libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
905 michael 5052 {
906 michael 8131 struct sockaddr_in *bind_ip;
907 michael 5671 struct sockaddr_in *addr; /* Outgoing host */
908     struct sockaddr_in local_addr; /* For binding */
909 michael 5052
910 michael 8131 addr = &scan->addr; /* Already have the IP in byte format from opm_scan */
911 michael 5671 addr->sin_family = AF_INET;
912     addr->sin_port = htons(conn->port);
913 michael 5052
914 michael 8131 bind_ip = (struct sockaddr_in *)libopm_config(scanner->config, OPM_CONFIG_BIND_IP);
915 michael 5052
916 michael 5948 conn->fd = socket(AF_INET, SOCK_STREAM, 0);
917 michael 5671 scanner->fd_use++; /* Increase file descriptor use */
918 michael 5052
919 michael 5671 if (conn->fd == -1)
920     {
921     libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD);
922     conn->state = OPM_STATE_CLOSED;
923     return;
924     }
925 michael 5052
926 michael 5671 if (bind_ip)
927     {
928     memset(&local_addr, 0, sizeof(local_addr));
929 michael 5052
930 michael 8131 local_addr.sin_addr.s_addr = bind_ip->sin_addr.s_addr;
931 michael 5671 local_addr.sin_family = AF_INET;
932     local_addr.sin_port = htons(0);
933    
934 michael 6072 if (bind(conn->fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1)
935 michael 5671 {
936     libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND);
937 michael 5052 conn->state = OPM_STATE_CLOSED;
938     return;
939 michael 5671 }
940     }
941 michael 5052
942 michael 5671 /* Set socket non blocking */
943     fcntl(conn->fd, F_SETFL, O_NONBLOCK);
944 michael 5052
945 michael 5671 connect(conn->fd, (struct sockaddr *)addr, sizeof(*addr));
946 michael 5052
947 michael 6222 #ifdef HAVE_LIBCRYPTO
948     if (conn->protocol->use_tls)
949     SSL_set_fd(conn->tls_handle, conn->fd);
950     #endif
951    
952 michael 5671 conn->state = OPM_STATE_ESTABLISHED;
953     time(&conn->creation); /* Stamp creation time, for timeout */
954 michael 5052 }
955    
956     /* check_poll
957     *
958     * Check sockets for ready read/write
959     *
960     * Parameters:
961     * scanner: Scanner to isolate check on
962     * Return:
963     * None
964     */
965 michael 5325 static void
966     libopm_check_poll(OPM_T *scanner)
967 michael 5052 {
968 michael 5671 OPM_NODE_T *node1, *node2;
969     OPM_SCAN_T *scan;
970     OPM_CONNECTION_T *conn;
971     unsigned int size = 0;
972     static unsigned int ufds_size;
973     static struct pollfd *ufds = NULL;
974 michael 5052
975 michael 5671 /* Grow pollfd array (ufds) as needed */
976     if (ufds_size < (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)))
977     {
978 michael 8206 libopm_free(ufds);
979 michael 5052
980 michael 8206 ufds = libopm_calloc((sizeof *ufds) * (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)));
981 michael 5671 ufds_size = (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT));
982     }
983 michael 5052
984 michael 5671 if (LIST_SIZE(scanner->scans) == 0)
985     return;
986 michael 5052
987 michael 5671 LIST_FOREACH(node1, scanner->scans->head)
988     {
989     scan = node1->data;
990 michael 5052
991 michael 5671 LIST_FOREACH(node2, scan->connections->head)
992     {
993     if (size >= ufds_size)
994     break;
995 michael 5052
996 michael 5671 conn = node2->data;
997 michael 5052
998 michael 5671 if (conn->state < OPM_STATE_ESTABLISHED ||
999     conn->state == OPM_STATE_CLOSED)
1000     continue;
1001 michael 5052
1002 michael 5671 ufds[size].events = 0;
1003     ufds[size].revents = 0;
1004     ufds[size].fd = conn->fd;
1005 michael 5052
1006 michael 5671 /* Check for HUNG UP. */
1007     ufds[size].events |= POLLHUP;
1008     /* Check for INVALID FD */
1009     ufds[size].events |= POLLNVAL;
1010    
1011     switch (conn->state)
1012     {
1013     case OPM_STATE_ESTABLISHED:
1014     ufds[size].events |= POLLOUT;
1015     break;
1016     case OPM_STATE_NEGSENT:
1017     ufds[size].events |= POLLIN;
1018     break;
1019 michael 5052 }
1020    
1021 michael 5671 size++;
1022     }
1023     }
1024 michael 5052
1025 michael 5671 switch (poll(ufds, size, 0))
1026     {
1027     case -1:
1028     /* error in select/poll */
1029     return;
1030     case 0:
1031     /* Nothing to do */
1032     return;
1033 michael 5052
1034 michael 5671 /* Pass pointer to connection to handler. */
1035     }
1036    
1037     LIST_FOREACH(node1, scanner->scans->head)
1038     {
1039     scan = node1->data;
1040    
1041     LIST_FOREACH(node2, scan->connections->head)
1042     {
1043     conn = node2->data;
1044    
1045     for (unsigned int i = 0; i < size; ++i)
1046 michael 5052 {
1047 michael 5671 if ((ufds[i].fd == conn->fd) && (conn->state != OPM_STATE_CLOSED))
1048     {
1049     if (ufds[i].revents & POLLIN)
1050     libopm_do_readready(scanner, scan, conn);
1051     if (ufds[i].revents & POLLOUT)
1052     libopm_do_writeready(scanner, scan, conn);
1053     if (ufds[i].revents & POLLHUP)
1054     libopm_do_hup(scanner, scan, conn);
1055     }
1056 michael 5052 }
1057 michael 5671 }
1058     }
1059 michael 5052 }
1060    
1061 michael 6222 static int
1062     libopm_do_readready_tls(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1063     {
1064     #ifdef HAVE_LIBCRYPTO
1065     int max_read, length;
1066     char readbuf[LIBOPM_TLS_RECORD_SIZE];
1067    
1068     if (!SSL_is_init_finished(conn->tls_handle))
1069     return 0;
1070    
1071     if ((length = SSL_read(conn->tls_handle, readbuf, sizeof(readbuf))) <= 0)
1072     {
1073     switch (SSL_get_error(conn->tls_handle, length))
1074     {
1075     /* TBD: possibly could recover here from some errors */
1076     default:
1077     libopm_do_hup(scanner, scan, conn);
1078     return 0;
1079     }
1080     }
1081    
1082     max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1083    
1084     for (const char *p = readbuf, *end = readbuf + length; p < end; ++p)
1085     {
1086     conn->bytes_read++;
1087    
1088     if (conn->bytes_read >= max_read)
1089     {
1090     libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1091     conn->state = OPM_STATE_CLOSED;
1092     return 0;
1093     }
1094    
1095     if (*p == '\0' || *p == '\r')
1096     continue;
1097    
1098     if (*p == '\n')
1099     {
1100     conn->readbuf[conn->readlen] = '\0';
1101     conn->readlen = 0;
1102    
1103     libopm_do_read(scanner, scan, conn);
1104    
1105     if (conn->state == OPM_STATE_CLOSED)
1106     return 0;
1107    
1108     continue;
1109     }
1110    
1111     if (conn->readlen < READBUFLEN)
1112     conn->readbuf[++(conn->readlen) - 1] = *p; /* -1 to pad for null term */
1113     }
1114     #endif
1115     return 0;
1116     }
1117    
1118 michael 5052 /* do_readready
1119     *
1120 michael 5909 * Remote connection is read ready, read the data into a buffer and check it against
1121     * the target_string if neccessary
1122 michael 5052 *
1123     * Parameters:
1124     * scanner: Scanner doing the scan
1125     * scan: Specific scan
1126     * conn: Specific connection in the scan
1127     *
1128     * Return:
1129     * None
1130     */
1131 michael 5325 static void
1132     libopm_do_readready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1133 michael 5052 {
1134 michael 5671 int max_read;
1135     char c;
1136 michael 5052
1137 michael 5671 /*
1138     * If protocol has a specific read function, call that instead of
1139     * reading data from here.
1140     */
1141     if (conn->protocol->read_function)
1142     {
1143     conn->protocol->read_function(scanner, scan, conn);
1144     return;
1145     }
1146 michael 5052
1147 michael 5671 max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1148 michael 5052
1149 michael 5671 while (1)
1150     {
1151     switch (read(conn->fd, &c, 1))
1152     {
1153     case 0:
1154     libopm_do_hup(scanner, scan, conn);
1155     return;
1156 michael 5052
1157 michael 5671 case -1:
1158     if (errno != EAGAIN)
1159     libopm_do_hup(scanner, scan, conn);
1160     return;
1161 michael 5052
1162 michael 5671 default:
1163     conn->bytes_read++;
1164 michael 5052
1165 michael 5671 if (conn->bytes_read >= max_read)
1166     {
1167     libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1168     conn->state = OPM_STATE_CLOSED;
1169     return;
1170     }
1171 michael 5052
1172 michael 5671 if (c == '\0' || c == '\r')
1173     continue;
1174 michael 5052
1175 michael 5671 if (c == '\n')
1176     {
1177     conn->readbuf[conn->readlen] = '\0';
1178     conn->readlen = 0;
1179 michael 5052
1180 michael 5671 libopm_do_read(scanner, scan, conn);
1181 michael 5052
1182 michael 5671 if (conn->state == OPM_STATE_CLOSED)
1183     return;
1184 michael 5052
1185 michael 5671 continue;
1186     }
1187 michael 5052
1188 michael 5671 if (conn->readlen < READBUFLEN)
1189     conn->readbuf[++(conn->readlen) - 1] = c; /* -1 to pad for null term */
1190     }
1191     }
1192 michael 5052 }
1193    
1194     /* do_read
1195     *
1196     * A line of data has been read from the socket, check it against
1197     * target string.
1198     *
1199     *
1200 michael 5325 *
1201 michael 5052 * Parameters:
1202     * scanner: Scanner doing the scan
1203     * scan: Specific scan
1204     * conn: Specific connection in the scan
1205     *
1206     * Return:
1207     * None
1208     */
1209 michael 5325 static void
1210     libopm_do_read(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1211 michael 5052 {
1212 michael 5325 OPM_LIST_T *list;
1213     OPM_NODE_T *node;
1214 michael 5052
1215 michael 5325 /* Check readbuf against target strings */
1216     list = (OPM_LIST_T *)libopm_config(scanner->config, OPM_CONFIG_TARGET_STRING);
1217    
1218     LIST_FOREACH(node, list->head)
1219     {
1220 michael 6075 const char *target_string = node->data;
1221 michael 5325
1222     if (strstr(conn->readbuf, target_string))
1223     {
1224     libopm_do_openproxy(scanner, scan, conn);
1225     break;
1226     }
1227     }
1228 michael 5052 }
1229    
1230     /* do_openproxy
1231     *
1232 michael 5909 * An open proxy was found on connection conn. Cleanup the connection and
1233 michael 5052 * call the appropriate callback to let the client know the proxy was found.
1234     *
1235     * Parameters:
1236     * scanner: Scanner doing the scan
1237     * scan: Specific scan
1238     * conn: Specific connection in the scan
1239     *
1240     * Return:
1241     * None
1242     */
1243 michael 5325 static void
1244     libopm_do_openproxy(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1245 michael 5052 {
1246 michael 5325 /* Mark the connection for close */
1247     conn->state = OPM_STATE_CLOSED;
1248 michael 5052
1249 michael 5325 /* Call client's open proxy callback */
1250     libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_OPENPROXY, 0);
1251 michael 5052 }
1252    
1253     /* do_writeready
1254     *
1255     * Remote connection is write ready, call the specific protocol
1256     * function for writing to this socket.
1257     *
1258     * Parameters:
1259     * scanner: Scanner doing the scan
1260     * scan: Specific scan
1261     * conn: Specific connection in the scan
1262     *
1263     * Return:
1264     * None
1265     */
1266 michael 5325 static void
1267     libopm_do_writeready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1268 michael 5052 {
1269 michael 5325 OPM_PROTOCOL_T *protocol;
1270 michael 5052
1271 michael 6222 #ifdef HAVE_LIBCRYPTO
1272     if (conn->protocol->use_tls)
1273     {
1274     if (!SSL_is_init_finished(conn->tls_handle))
1275     {
1276     SSL_connect(conn->tls_handle);
1277     return;
1278     }
1279     }
1280     #endif
1281    
1282 michael 5325 protocol = conn->protocol;
1283 michael 5052
1284 michael 5325 /* Call write function for specific protocol */
1285     if (protocol->write_function)
1286     protocol->write_function(scanner, scan, conn);
1287 michael 5052
1288 michael 5325 /* Flag as NEGSENT so we don't have to send data again*/
1289     conn->state = OPM_STATE_NEGSENT;
1290 michael 5052 }
1291    
1292     /* do_hup
1293     *
1294     * Connection ended prematurely
1295     *
1296     * Parameters:
1297     * scanner: Scanner doing the scan
1298     * scan: Specific scan
1299     * conn: Specific connection in the scan
1300     * error: OPM_ERR_T containing the error type
1301     * Return:
1302     * None
1303     */
1304 michael 5325 static void
1305     libopm_do_hup(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1306 michael 5052 {
1307     /* Mark the connection for close */
1308 michael 5325 conn->state = OPM_STATE_CLOSED;
1309 michael 5052
1310 michael 5325 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_NEGFAIL, 0);
1311 michael 5052 }
1312    
1313     /* do_callback
1314 michael 5909 *
1315 michael 5052 * Call callback
1316     *
1317     * Parameters:
1318     * scanner: scanner remote is on
1319     * remote: remote callback is for
1320     * type: callback type
1321     * var: optional var passed back (error codes, etc )
1322     * Return:
1323     * None
1324     */
1325 michael 5325 static void
1326     libopm_do_callback(OPM_T *scanner, OPM_REMOTE_T *remote, int type, int var)
1327 michael 5052 {
1328 michael 5325 /* Callback is out of range */
1329 michael 5673 if (type < 0 || type >= CBLEN)
1330 michael 5325 return;
1331 michael 5052
1332 michael 5325 if (scanner->callbacks[type].func)
1333     (scanner->callbacks[type].func)(scanner, remote, var, scanner->callbacks[type].data);
1334 michael 5052 }
1335    
1336     /* setup_remote
1337     *
1338     * Setup an OPM_REMOTE_T with information from an OPM_CONNECTION_T
1339     * for callback
1340     *
1341     * Parameters:
1342     * remote, conn
1343 michael 5325 *
1344 michael 5052 * Return:
1345     * remote
1346     */
1347 michael 5325 static OPM_REMOTE_T *
1348     libopm_setup_remote(OPM_REMOTE_T *remote, OPM_CONNECTION_T *conn)
1349 michael 5052 {
1350 michael 5325 remote->port = conn->port;
1351     remote->bytes_read = conn->bytes_read;
1352     remote->protocol = conn->protocol->type;
1353 michael 5052
1354 michael 5325 return remote;
1355 michael 5052 }

Properties

Name Value
svn:eol-style native
svn:keywords Id