00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include <errno.h>
00067 #include <stdlib.h>
00068 #include <sys/types.h>
00069 #include <netinet/in.h>
00070
00071 #include "msg.h"
00072 #include "gwlib/gwlib.h"
00073
00074
00075
00076
00077
00078 static void append_integer(Octstr *os, long i);
00079 static void append_string(Octstr *os, Octstr *field);
00080 static void append_uuid(Octstr *os, uuid_t id);
00081
00082 static int parse_integer(long *i, Octstr *packed, int *off);
00083 static int parse_string(Octstr **os, Octstr *packed, int *off);
00084 static int parse_uuid(uuid_t id, Octstr *packed, int *off);
00085
00086 static char *type_as_str(Msg *msg);
00087
00088
00089
00090
00091
00092
00093 Msg *msg_create_real(enum msg_type type, const char *file, long line,
00094 const char *func)
00095 {
00096 Msg *msg;
00097
00098 msg = gw_malloc_trace(sizeof(Msg), file, line, func);
00099
00100 msg->type = type;
00101 #define INTEGER(name) p->name = MSG_PARAM_UNDEFINED
00102 #define OCTSTR(name) p->name = NULL
00103 #define UUID(name) uuid_generate(p->name)
00104 #define VOID(name) p->name = NULL
00105 #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
00106 #include "msg-decl.h"
00107
00108 return msg;
00109 }
00110
00111 Msg *msg_duplicate(Msg *msg)
00112 {
00113 Msg *new;
00114
00115 new = msg_create(msg->type);
00116
00117 #define INTEGER(name) p->name = q->name
00118 #define OCTSTR(name) \
00119 if (q->name == NULL) p->name = NULL; \
00120 else p->name = octstr_duplicate(q->name);
00121 #define UUID(name) uuid_copy(p->name, q->name)
00122 #define VOID(name) p->name = q->name
00123 #define MSG(type, stmt) { \
00124 struct type *p = &new->type; \
00125 struct type *q = &msg->type; \
00126 stmt }
00127 #include "msg-decl.h"
00128
00129 return new;
00130 }
00131
00132 void msg_destroy(Msg *msg)
00133 {
00134 if (msg == NULL)
00135 return;
00136
00137 #define INTEGER(name) p->name = 0
00138 #define OCTSTR(name) octstr_destroy(p->name)
00139 #define UUID(name) uuid_clear(p->name)
00140 #define VOID(name)
00141 #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
00142 #include "msg-decl.h"
00143
00144 gw_free(msg);
00145 }
00146
00147 void msg_destroy_item(void *msg)
00148 {
00149 msg_destroy(msg);
00150 }
00151
00152 void msg_dump(Msg *msg, int level)
00153 {
00154 char buf[UUID_STR_LEN + 1];
00155
00156 debug("gw.msg", 0, "%*sMsg object at %p:", level, "", (void *) msg);
00157 debug("gw.msg", 0, "%*s type: %s", level, "", type_as_str(msg));
00158 #define INTEGER(name) \
00159 debug("gw.msg", 0, "%*s %s.%s: %ld", level, "", t, #name, (long) p->name)
00160 #define OCTSTR(name) \
00161 debug("gw.msg", 0, "%*s %s.%s:", level, "", t, #name); \
00162 octstr_dump(p->name, level + 1)
00163 #define UUID(name) \
00164 uuid_unparse(p->name, buf); \
00165 debug("gw.msg", 0 , "%*s %s.%s: %s", level, "", t, #name, buf)
00166 #define VOID(name) \
00167 debug("gw.msg", 0, "%*s %s.%s: %p", level, "", t, #name, p->name)
00168 #define MSG(tt, stmt) \
00169 if (tt == msg->type) \
00170 { char *t = #tt; struct tt *p = &msg->tt; stmt }
00171 #include "msg-decl.h"
00172 debug("gw.msg", 0, "Msg object ends.");
00173 }
00174
00175
00176 enum msg_type msg_type(Msg *msg)
00177 {
00178 return msg->type;
00179 }
00180
00181 Octstr *msg_pack(Msg *msg)
00182 {
00183 Octstr *os;
00184
00185 os = octstr_create("");
00186 append_integer(os, msg->type);
00187
00188 #define INTEGER(name) append_integer(os, p->name)
00189 #define OCTSTR(name) append_string(os, p->name)
00190 #define UUID(name) append_uuid(os, p->name)
00191 #define VOID(name)
00192 #define MSG(type, stmt) \
00193 case type: { struct type *p = &msg->type; stmt } break;
00194
00195 switch (msg->type) {
00196 #include "msg-decl.h"
00197 default:
00198 panic(0, "Internal error: unknown message type %d",
00199 msg->type);
00200 }
00201
00202 return os;
00203 }
00204
00205
00206 Msg *msg_unpack_real(Octstr *os, const char *file, long line, const char *func)
00207 {
00208 Msg *msg;
00209 int off;
00210 long i;
00211
00212 msg = msg_create_real(0, file, line, func);
00213 if (msg == NULL)
00214 goto error;
00215
00216 off = 0;
00217
00218 if (parse_integer(&i, os, &off) == -1)
00219 goto error;
00220 msg->type = i;
00221
00222 #define INTEGER(name) \
00223 if (parse_integer(&(p->name), os, &off) == -1) goto error
00224 #define OCTSTR(name) \
00225 if (parse_string(&(p->name), os, &off) == -1) goto error
00226 #define UUID(name) \
00227 if (parse_uuid(p->name, os, &off) == -1) goto error
00228 #define VOID(name)
00229 #define MSG(type, stmt) \
00230 case type: { struct type *p = &(msg->type); stmt } break;
00231
00232 switch (msg->type) {
00233 #include "msg-decl.h"
00234 default:
00235 panic(0, "Internal error: unknown message type: %d",
00236 msg->type);
00237 }
00238
00239 return msg;
00240
00241 error:
00242 if (msg != NULL) msg_destroy(msg);
00243 error(0, "Msg packet was invalid.");
00244 return NULL;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 inline Msg *msg_unpack_wrapper(Octstr *os)
00254 {
00255 return msg_unpack(os);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264 static void append_integer(Octstr *os, long i)
00265 {
00266 unsigned char buf[4];
00267
00268 encode_network_long(buf, i);
00269 octstr_append_data(os, (char *)buf, 4);
00270 }
00271
00272 static void append_string(Octstr *os, Octstr *field)
00273 {
00274 if (field == NULL)
00275 append_integer(os, -1);
00276 else {
00277 append_integer(os, octstr_len(field));
00278 octstr_insert(os, field, octstr_len(os));
00279 }
00280 }
00281
00282 static void append_uuid(Octstr *os, uuid_t id)
00283 {
00284 char buf[UUID_STR_LEN + 1];
00285
00286 uuid_unparse(id, buf);
00287 append_integer(os, UUID_STR_LEN);
00288 octstr_append_cstr(os, buf);
00289 }
00290
00291 static int parse_integer(long *i, Octstr *packed, int *off)
00292 {
00293 unsigned char buf[4];
00294
00295 gw_assert(*off >= 0);
00296 if (*off + 4 > octstr_len(packed)) {
00297 error(0, "Packet too short while unpacking Msg.");
00298 return -1;
00299 }
00300
00301 octstr_get_many_chars((char *)buf, packed, *off, 4);
00302 *i = decode_network_long(buf);
00303 *off += 4;
00304 return 0;
00305 }
00306
00307
00308 static int parse_string(Octstr **os, Octstr *packed, int *off)
00309 {
00310 long len;
00311
00312 if (parse_integer(&len, packed, off) == -1)
00313 return -1;
00314
00315 if (len == -1) {
00316 *os = NULL;
00317 return 0;
00318 }
00319
00320
00321
00322 *os = octstr_copy(packed, *off, len);
00323 if (*os == NULL)
00324 return -1;
00325 *off += len;
00326
00327 return 0;
00328 }
00329
00330
00331 static int parse_uuid(uuid_t id, Octstr *packed, int *off)
00332 {
00333 Octstr *tmp = NULL;
00334
00335 if (parse_string(&tmp, packed, off) == -1) {
00336 octstr_destroy(tmp);
00337 return -1;
00338 }
00339
00340 if (uuid_parse(octstr_get_cstr(tmp), id) == -1) {
00341 octstr_destroy(tmp);
00342 return -1;
00343 }
00344
00345 octstr_destroy(tmp);
00346
00347 return 0;
00348 }
00349
00350 static char *type_as_str(Msg *msg)
00351 {
00352 switch (msg->type) {
00353 #define MSG(t, stmt) case t: return #t;
00354 #include "msg-decl.h"
00355 default:
00356 return "unknown type";
00357 }
00358 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.