void rmq_destroy(evi_reply_sock *sock) { if (!sock) return; if ((sock->flags & EVI_ADDRESS) && sock->address.s) shm_free(sock->address.s); if ((sock->flags & EVI_PARAMS) && sock->params) { rmq_free_param((rmq_params_t *)sock->params); rmq_destroy_param((rmq_params_t *)sock->params); } shm_free(sock); }
/* * This is the parsing function * The socket grammar should be: * [user [':' password] '@'] ip [':' port] '/' exchange */ static evi_reply_sock* rmq_parse(str socket) { evi_reply_sock *sock = NULL; rmq_params_t *param; unsigned int len, i; const char* begin; str prev_token; enum state { ST_USER_HOST, /* Username or hostname */ ST_PASS_PORT, /* Password or port part */ ST_HOST, /* Hostname part */ ST_PORT, /* Port part */ } st; if (!socket.len || !socket.s) { LM_ERR("no socket specified\n"); return NULL; } sock = shm_malloc(sizeof(evi_reply_sock) + sizeof(rmq_params_t)); if (!sock) { LM_ERR("no more memory for socket\n"); return NULL; } memset(sock, 0, sizeof(evi_reply_sock) + sizeof(rmq_params_t)); param = (rmq_params_t*)(sock + 1); prev_token.s = 0; prev_token.len = 0; /* Initialize all attributes to 0 */ st = ST_USER_HOST; begin = socket.s; len = socket.len; for(i = 0; i < len; i++) { switch(st) { case ST_USER_HOST: switch(socket.s[i]) { case '@': st = ST_HOST; if (dupl_string(¶m->user, begin, socket.s + i)) goto err; begin = socket.s + i + 1; param->flags |= RMQ_PARAM_USER; break; case ':': st = ST_PASS_PORT; if (dupl_string(&prev_token, begin, socket.s + i) < 0) goto err; begin = socket.s + i + 1; break; case '/': if (dupl_string(&sock->address, begin, socket.s + i) < 0) goto err; sock->flags |= EVI_ADDRESS; if (dupl_string(¶m->exchange, socket.s + i + 1, socket.s + len) < 0) goto err; param->flags |= RMQ_PARAM_EXCH; goto success; } break; case ST_PASS_PORT: switch(socket.s[i]) { case '@': st = ST_HOST; param->user.len = prev_token.len; param->user.s = prev_token.s; param->flags |= RMQ_PARAM_USER; prev_token.s = 0; if (dupl_string(¶m->pass, begin, socket.s + i) < 0) goto err; param->flags |= RMQ_PARAM_PASS; begin = socket.s + i + 1; break; case '/': sock->address.len = prev_token.len; sock->address.s = prev_token.s; prev_token.s = 0; sock->flags |= EVI_ADDRESS; sock->port = str2s(begin, socket.s + i - begin, 0); if (!sock->port) { LM_DBG("malformed port: %.*s\n", (int)(socket.s + i - begin), begin); goto err; } sock->flags |= EVI_PORT; if (dupl_string(¶m->exchange, socket.s + i + 1, socket.s + len) < 0) goto err; param->flags |= RMQ_PARAM_EXCH; goto success; } break; case ST_HOST: switch(socket.s[i]) { case ':': st = ST_PORT; if (dupl_string(&sock->address, begin, socket.s + i) < 0) goto err; sock->flags |= EVI_ADDRESS; begin = socket.s + i + 1; break; case '/': if (dupl_string(&sock->address, begin, socket.s + i) < 0) goto err; sock->flags |= EVI_ADDRESS; if (dupl_string(¶m->exchange, socket.s + i + 1, socket.s + len) < 0) goto err; param->flags |= RMQ_PARAM_EXCH; goto success; } break; case ST_PORT: switch(socket.s[i]) { case '/': sock->port = str2s(begin, socket.s + i - begin, 0); if (!sock->port) { LM_DBG("malformed port: %.*s\n", (int)(socket.s + i - begin), begin); goto err; } sock->flags |= EVI_PORT; if (dupl_string(¶m->exchange, socket.s + i + 1, socket.s + len) < 0) goto err; param->flags |= RMQ_PARAM_EXCH; goto success; } break; } } LM_WARN("not implemented %.*s\n", socket.len, socket.s); goto err; success: if (!(sock->flags & EVI_PORT) || !sock->port) { sock->port = RMQ_DEFAULT_PORT; sock->flags |= EVI_PORT; } if (!(param->flags & RMQ_PARAM_USER) || !param->user.s) { param->user.s = param->pass.s = RMQ_DEFAULT_UP; param->user.len = param->pass.len = RMQ_DEFAULT_UP_LEN; param->flags |= RMQ_PARAM_USER|RMQ_PARAM_PASS; } sock->params = param; sock->flags |= EVI_PARAMS | RMQ_FLAG; return sock; err: LM_ERR("error while parsing socket %.*s\n", socket.len, socket.s); if (prev_token.s) shm_free(prev_token.s); rmq_free_param(param); if (sock->address.s) shm_free(sock->address.s); shm_free(sock); return NULL; }