static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done) { datagram_stream dtgram; int ret; my_socket_address *p; int reply_sock, flags; p = (my_socket_address *)hdl->param; LM_DBG("the socket domain is %i and af_local is %i\n", p->domain, AF_LOCAL); memset(&dtgram, 0, sizeof(dtgram)); mi_create_dtgram_replysocket(reply_sock, p->domain, err); if (mi_rpl!=0) { /*allocate the response datagram*/ dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE); if(!dtgram.start) { LM_ERR("no more pkg memory\n"); goto err; } /*build the response*/ if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0) { LM_ERR("failed to build the response \n"); goto err; } LM_DBG("the response is %s", dtgram.start); /*send the response*/ ret = mi_send_dgram(reply_sock, dtgram.start, dtgram.current - dtgram.start, (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout); if (ret>0) { LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); } else { LM_ERR("failed to send the response, ret is %i\n",ret); } free_mi_tree(mi_rpl); pkg_free(dtgram.start); if (done) free_async_handler( hdl ); } else if (done) { mi_send_dgram(reply_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout); free_async_handler( hdl ); } close(reply_sock); return; err: if(dtgram.start) pkg_free(dtgram.start); close(reply_sock); if (done) free_async_handler( hdl ); return; }
int mi_init_datagram_server(sockaddr_dtgram *addr, unsigned int socket_domain, rx_tx_sockets * socks, int mode, int uid, int gid ) { char * socket_name; /* create sockets rx and tx ... */ /***********************************/ mi_socket_domain = socket_domain; /**********************************/ socks->rx_sock = socket(socket_domain, SOCK_DGRAM, 0); if (socks->rx_sock == -1) { LM_ERR("cannot create RX socket: %s\n", strerror(errno)); return -1; } switch(socket_domain) { case AF_LOCAL: LM_DBG("we have a unix socket: %s\n", addr->unix_addr.sun_path); socket_name = addr->unix_addr.sun_path; if(bind(socks->rx_sock,(struct sockaddr*)&addr->unix_addr, SUN_LEN(&addr->unix_addr))< 0) { LM_ERR("bind: %s\n", strerror(errno)); goto err_rx; } if(mi_sock_check(socks->rx_sock, socket_name)!=0) goto err_rx; /* change permissions */ if (mode){ if (chmod(socket_name, mode)<0){ LM_ERR("failed to change the permissions for %s to %04o:" "%s[%d]\n",socket_name, mode, strerror(errno), errno); goto err_rx; } } /* change ownership */ if ((uid!=-1) || (gid!=-1)){ if (chown(socket_name, uid, gid)<0){ LM_ERR("failed to change the owner/group for %s to %d.%d;" "%s[%d]\n",socket_name, uid, gid, strerror(errno), errno); goto err_rx; } } break; case AF_INET: if (bind(socks->rx_sock, &addr->udp_addr.s, sockaddru_len(addr->udp_addr))< 0) { LM_ERR("bind: %s\n", strerror(errno)); goto err_rx; } break; #ifdef USE_IPV6 case AF_INET6: if(bind(socks->rx_sock, (struct sockaddr*)&addr->udp_addr.sin6, sizeof(addr->udp_addr)) < 0) { LM_ERR("bind: %s\n", strerror(errno)); goto err_rx; } break; #endif default: LM_ERR("domain not supported\n"); goto err_both; } mi_create_dtgram_replysocket(socks->tx_sock,socket_domain, err_both); return 0; err_both: close(socks->tx_sock); err_rx: close(socks->rx_sock); return -1; }