d5c9aeb03db385309f12395cd2fe8512c18ba406
[oweals/tinc.git] / src / protocol_misc.c
1 /*
2     protocol_misc.c -- handle the meta-protocol, miscellaneous functions
3     Copyright (C) 1999-2003 Ivo Timmermans <ivo@o2w.nl>,
4                   2000-2003 Guus Sliepen <guus@sliepen.eu.org>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id: protocol_misc.c,v 1.1.4.10 2003/07/12 17:41:47 guus Exp $
21 */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <errno.h>
30
31 #include <utils.h>
32
33 #include "conf.h"
34 #include "net.h"
35 #include "netutl.h"
36 #include "protocol.h"
37 #include "meta.h"
38 #include "connection.h"
39 #include "logger.h"
40
41 #include "system.h"
42
43 /* Status and error notification routines */
44
45 int send_status(connection_t *c, int statusno, char *statusstring)
46 {
47         cp();
48
49         if(!statusstring)
50                 statusstring = "Status";
51
52         return send_request(c, "%d %d %s", STATUS, statusno, statusstring);
53 }
54
55 int status_h(connection_t *c)
56 {
57         int statusno;
58         char statusstring[MAX_STRING_SIZE];
59
60         cp();
61
62         if(sscanf(c->buffer, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
63                 logger(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
64                            c->name, c->hostname);
65                 return -1;
66         }
67
68         ifdebug(STATUS) logger(LOG_NOTICE, _("Status message from %s (%s): %d: %s"),
69                            c->name, c->hostname, statusno, statusstring);
70
71         return 0;
72 }
73
74 int send_error(connection_t *c, int err, char *errstring)
75 {
76         cp();
77
78         if(!errstring)
79                 errstring = "Error";
80
81         return send_request(c, "%d %d %s", ERROR, err, errstring);
82 }
83
84 int error_h(connection_t *c)
85 {
86         int err;
87         char errorstring[MAX_STRING_SIZE];
88
89         cp();
90
91         if(sscanf(c->buffer, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
92                 logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
93                            c->name, c->hostname);
94                 return -1;
95         }
96
97         ifdebug(ERROR) logger(LOG_NOTICE, _("Error message from %s (%s): %d: %s"),
98                            c->name, c->hostname, err, errorstring);
99
100         terminate_connection(c, c->status.active);
101
102         return 0;
103 }
104
105 int send_termreq(connection_t *c)
106 {
107         cp();
108
109         return send_request(c, "%d", TERMREQ);
110 }
111
112 int termreq_h(connection_t *c)
113 {
114         cp();
115
116         terminate_connection(c, c->status.active);
117
118         return 0;
119 }
120
121 int send_ping(connection_t *c)
122 {
123         cp();
124
125         c->status.pinged = 1;
126         c->last_ping_time = now;
127
128         return send_request(c, "%d", PING);
129 }
130
131 int ping_h(connection_t *c)
132 {
133         cp();
134
135         return send_pong(c);
136 }
137
138 int send_pong(connection_t *c)
139 {
140         cp();
141
142         return send_request(c, "%d", PONG);
143 }
144
145 int pong_h(connection_t *c)
146 {
147         cp();
148
149         c->status.pinged = 0;
150
151         /* Succesful connection, reset timeout if this is an outgoing connection. */
152
153         if(c->outgoing)
154                 c->outgoing->timeout = 0;
155
156         return 0;
157 }
158
159 /* Sending and receiving packets via TCP */
160
161 int send_tcppacket(connection_t *c, vpn_packet_t *packet)
162 {
163         int x;
164
165         cp();
166
167         /* Evil hack. */
168
169         x = send_request(c, "%d %hd", PACKET, packet->len);
170
171         if(x)
172                 return x;
173
174         return send_meta(c, packet->data, packet->len);
175 }
176
177 int tcppacket_h(connection_t *c)
178 {
179         short int len;
180
181         cp();
182
183         if(sscanf(c->buffer, "%*d %hd", &len) != 1) {
184                 logger(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name,
185                            c->hostname);
186                 return -1;
187         }
188
189         /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
190
191         c->tcplen = len;
192
193         return 0;
194 }