Connect to hard-coded peer and exchange route info. Buggy and incomplete.
[trust_router.git] / trp / trpc.c
1 #include <fcntl.h>
2 #include <talloc.h>
3 #include <errno.h>
4 #include <unistd.h>
5
6 #include <gsscon.h>
7 #include <tr_rp.h>
8 #include <tr_debug.h>
9 #include <trp_internal.h>
10
11 static int trpc_destructor(void *object)
12 {
13   TRPC_INSTANCE *trpc=talloc_get_type_abort(object, TRPC_INSTANCE);
14   if (trpc->gssname!=NULL)
15     tr_free_name(trpc->gssname);
16   return 0;
17 }
18
19 /* also allocates the incoming mq */
20 TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx)
21 {
22   TRPC_INSTANCE *trpc=talloc(mem_ctx, TRPC_INSTANCE);
23   if (trpc!=NULL) {
24     trpc->next=NULL;
25     trpc->server=NULL;
26     trpc->port=0;
27     trpc->conn=NULL;
28     trpc->dh=NULL;
29     trpc->mq=tr_mq_new(trpc);
30     if (trpc->mq==NULL) {
31       talloc_free(trpc);
32       trpc=NULL;
33     } else
34       talloc_set_destructor((void *)trpc, trpc_destructor);
35     
36   }
37   return trpc;
38 }
39
40 void trpc_free (TRPC_INSTANCE *trpc)
41 {
42   if (trpc)
43     talloc_free(trpc);
44 }
45
46 TRPC_INSTANCE *trpc_get_next(TRPC_INSTANCE *trpc)
47 {
48   return trpc->next;
49 }
50
51 void trpc_set_next(TRPC_INSTANCE *trpc, TRPC_INSTANCE *next)
52 {
53   trpc->next=next;
54 }
55
56 /* Ok to call more than once; guarantees trpc no longer in the list. Does not free removed element.
57  * Returns handle to new list, you must replace your old handle on the list with this.  */
58 TRPC_INSTANCE *trpc_remove(TRPC_INSTANCE *trpc, TRPC_INSTANCE *remove)
59 {
60   TRPC_INSTANCE *cur=trpc;
61   TRPC_INSTANCE *last=NULL;
62
63   if (cur==NULL)
64     return NULL;
65
66   /* first element is a special case */
67   if (cur==remove) {
68     trpc=trpc_get_next(cur); /* advance list head */
69   } else {
70     /* it was not the first element */
71     last=cur;
72     cur=trpc_get_next(cur);
73     while (cur!=NULL) {
74       if (cur==remove) {
75         trpc_set_next(last, trpc_get_next(cur));
76         break;
77       }
78       last=cur;
79       cur=trpc_get_next(cur);
80     }
81   }
82   return trpc;
83 }
84
85 static TRPC_INSTANCE *trpc_get_tail(TRPC_INSTANCE *trpc)
86 {
87   while((trpc!=NULL)&&(trpc_get_next(trpc)!=NULL))
88     trpc=trpc_get_next(trpc);
89   return trpc;
90 }
91
92 void trpc_append(TRPC_INSTANCE *trpc, TRPC_INSTANCE *new)
93 {
94   trpc_set_next(trpc_get_tail(trpc), new);
95 }
96
97 char *trpc_get_server(TRPC_INSTANCE *trpc)
98 {
99   return trpc->server;
100 }
101
102 void trpc_set_server(TRPC_INSTANCE *trpc, char *server)
103 {
104   trpc->server=server;
105 }
106
107 TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc)
108 {
109   return trpc->gssname;
110 }
111
112 /* takes responsibility for freeing gssname */
113 void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname)
114 {
115   trpc->gssname=gssname;
116 }
117
118 unsigned int trpc_get_port(TRPC_INSTANCE *trpc)
119 {
120   return trpc->port;
121 }
122
123 void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port)
124 {
125   trpc->port=port;
126 }
127
128 TRP_CONNECTION *trpc_get_conn(TRPC_INSTANCE *trpc)
129 {
130   return trpc->conn;
131 }
132
133 void trpc_set_conn(TRPC_INSTANCE *trpc, TRP_CONNECTION *conn)
134 {
135   trpc->conn=conn;
136 }
137
138 DH *trpc_get_dh(TRPC_INSTANCE *trpc)
139 {
140   return trpc->dh;
141 }
142
143 void trpc_set_dh(TRPC_INSTANCE *trpc, DH *dh)
144 {
145   trpc->dh=dh;
146 }
147
148 TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc)
149 {
150   return trp_connection_get_status(trpc_get_conn(trpc));
151 }
152
153 TR_MQ *trpc_get_mq(TRPC_INSTANCE *trpc)
154 {
155   return trpc->mq;
156 }
157
158 void trpc_set_mq(TRPC_INSTANCE *trpc, TR_MQ *mq)
159 {
160   trpc->mq=mq;
161 }
162
163 /* submit msg to trpc for transmission */
164 void trpc_mq_append(TRPC_INSTANCE *trpc, TR_MQ_MSG *msg)
165 {
166   tr_mq_append(trpc->mq, msg);
167 }
168
169 TR_MQ_MSG *trpc_mq_pop(TRPC_INSTANCE *trpc)
170 {
171   return tr_mq_pop(trpc->mq);
172 }
173
174 TRP_RC trpc_connect(TRPC_INSTANCE *trpc)
175 {
176   return trp_connection_initiate(trpc_get_conn(trpc), trpc_get_server(trpc), trpc_get_port(trpc));
177 }
178
179 /* simple function, based on tidc_send_req */
180 TRP_RC trpc_send_msg (TRPC_INSTANCE *trpc, 
181                       const char *msg_content)
182 {
183   int err=0;
184   TRP_RC rc=TRP_SUCCESS;
185
186   /* Send the request over the connection */
187   if (err = gsscon_write_encrypted_token(trp_connection_get_fd(trpc_get_conn(trpc)),
188                                          *trp_connection_get_gssctx(trpc_get_conn(trpc)),
189                                          msg_content, 
190                                          strlen(msg_content))) {
191     tr_err( "trpc_send_msg: Error sending message over connection.\n");
192     rc=TRP_ERROR;
193   }
194   return rc;
195 }