/* * Send a reply, either positive or negative, to the client */ static int rpc_send(rpc_ctx_t* ctx) { struct iovec v[MAX_MSG_CHUNKS]; int f; int n; int ret; /* Send the reply only once */ if (ctx->reply_sent) return 1; else ctx->reply_sent = 1; if ((n=build_iovec(ctx, v, MAX_MSG_CHUNKS))<0) goto error; if (ctx->send_h->type==S_FIFO){ /* Open the reply file */ f = open_reply_pipe(ctx->reply_file); if (f == -1) { ERR("No reply pipe %s\n", ctx->reply_file); return -1; } ret=tsend_dgram_ev(f, v, n, FIFO_TX_TIMEOUT); close(f); }else{ ret=sock_send_v(ctx->send_h, v, n); } return (ret>=0)?0:-1; error: ERR("rpc_send fifo error\n"); return -1; }
static int write_to_unixsock(char* sockname, int cnt) { int len, e; struct sockaddr_un dest; if (!sockname) { LM_ERR("invalid parameter\n"); return E_UNSPEC; } len = strlen(sockname); if (len == 0) { LM_ERR("empty socket name\n"); return -1; } else if (len > 107) { LM_ERR("socket name too long\n"); return -1; } memset(&dest, 0, sizeof(dest)); dest.sun_family = PF_LOCAL; memcpy(dest.sun_path, sockname, len); #ifdef HAVE_SOCKADDR_SA_LEN dest.sun_len = len; #endif e = connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest)); #ifdef HAVE_CONNECT_ECONNRESET_BUG /* * Workaround for a nasty bug in BSD kernels dated back * to the Berkeley days, so that can be found in many modern * BSD-derived kernels. Workaround should be pretty harmless since * in normal conditions connect(2) can never return ECONNRESET. */ if ((e == -1) && (errno == ECONNRESET)) e = 0; #endif if (e == -1) { LM_ERR("failed to connect: %s\n", strerror(errno)); return -1; } if (tsend_dgram_ev(sock, (struct iovec*)(void*)lines_eol, 2 * cnt, tm_unix_tx_timeout * 1000) < 0) { LM_ERR("writev failed: %s\n", strerror(errno)); return -1; } return 0; }