1/* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
2
3#include "connection.h"
4#include "process.h"
5#include "authdb.h"
6#include "engine.h"
7#include "server.h"
8#include "debugging.h"
9
10struct _connection_s {
11    __AUTH_BASE_STRUCT_HEADER__;
12
13    process_t proc;
14    engine_t engine;
15    dispatch_queue_t dispatch_queue;
16    dispatch_queue_t dispatch_queue_internal;
17    bool sent_syslog_warn;
18};
19
20static void
21_connection_finalize(CFTypeRef value)
22{
23    connection_t conn = (connection_t)value;
24
25    process_remove_connection(conn->proc, conn);
26
27    dispatch_barrier_sync(conn->dispatch_queue, ^{});
28    dispatch_barrier_sync(conn->dispatch_queue_internal, ^{});
29
30    CFReleaseSafe(conn->proc);
31    CFReleaseNull(conn->engine);
32    dispatch_release(conn->dispatch_queue);
33    dispatch_release(conn->dispatch_queue_internal);
34}
35
36AUTH_TYPE_INSTANCE(connection,
37                   .init = NULL,
38                   .copy = NULL,
39                   .finalize = _connection_finalize,
40                   .equal = NULL,
41                   .hash = NULL,
42                   .copyFormattingDesc = NULL,
43                   .copyDebugDesc = NULL
44                   );
45
46static CFTypeID connection_get_type_id() {
47    static CFTypeID type_id = _kCFRuntimeNotATypeID;
48    static dispatch_once_t onceToken;
49
50    dispatch_once(&onceToken, ^{
51        type_id = _CFRuntimeRegisterClass(&_auth_type_connection);
52    });
53
54    return type_id;
55}
56
57connection_t
58connection_create(process_t proc)
59{
60    connection_t conn = NULL;
61
62    conn = (connection_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, connection_get_type_id(), AUTH_CLASS_SIZE(connection), NULL);
63    require(conn != NULL, done);
64
65    conn->proc = (process_t)CFRetain(proc);
66    conn->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
67    conn->dispatch_queue_internal = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
68
69done:
70    return conn;
71}
72
73pid_t connection_get_pid(connection_t conn)
74{
75    return process_get_pid(conn->proc);
76}
77
78process_t connection_get_process(connection_t conn)
79{
80    return conn->proc;
81}
82
83dispatch_queue_t connection_get_dispatch_queue(connection_t conn)
84{
85    return conn->dispatch_queue;
86}
87
88void connection_set_engine(connection_t conn, engine_t engine)
89{
90    dispatch_sync(conn->dispatch_queue_internal, ^{
91        if (engine) {
92            CFReleaseNull(conn->engine);
93            conn->engine = (engine_t)CFRetain(engine);
94        } else {
95            CFReleaseNull(conn->engine);
96        }
97    });
98}
99
100void connection_destory_agents(connection_t conn)
101{
102    dispatch_sync(conn->dispatch_queue_internal, ^{
103        if (conn->engine) {
104            engine_destroy_agents(conn->engine);
105        }
106    });
107}
108
109bool connection_get_syslog_warn(connection_t conn)
110{
111    return conn->sent_syslog_warn;
112}
113
114void connection_set_syslog_warn(connection_t conn)
115{
116    conn->sent_syslog_warn = true;
117}
118
119