X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=socket_server.c;h=e1853d3ec20241fbcd1f429d3f66e6c6e05c42bc;hp=469f562eb469247fac82ac770c189d75ed069979;hb=b1ab2b9ac1cfc15d2a8f5850145dd69043cc3ef7;hpb=16488a01568e7c35d0e7adf46fdfee5e488df8d8 diff --git a/socket_server.c b/socket_server.c index 469f562..e1853d3 100644 --- a/socket_server.c +++ b/socket_server.c @@ -15,7 +15,7 @@ #include -char *socket_name = SOCKET_NAME; +char socket_name[128]; int sock = -1; struct sockaddr_un sock_address; @@ -26,7 +26,7 @@ struct admin_list *admin_first = NULL; */ int admin_init(void) { - unsigned long on = 1; + unsigned int on = 1; /* open and bind socket */ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) @@ -36,6 +36,7 @@ int admin_init(void) } fhuse++; memset(&sock_address, 0, sizeof(sock_address)); + SPRINT(socket_name, SOCKET_NAME, options.lock); sock_address.sun_family = AF_UNIX; UCPY(sock_address.sun_path, socket_name); unlink(socket_name); @@ -66,6 +67,10 @@ int admin_init(void) PERROR("Failed to set socket \"%s\" into non-blocking mode. (errno=%d)\n", sock_address.sun_path, errno); return(-1); } + if (chmod(socket_name, options.socketrights) < 0) + { + PERROR("Failed to change socket rigts to %d. (errno=%d)\n", options.socketrights, errno); + } return(0); } @@ -80,10 +85,42 @@ void free_connection(struct admin_list *admin) void *temp; union parameter param; class Join *join, *joinnext; + struct mISDNport *mISDNport; + int i, ii; /* free remote joins */ if (admin->remote_name[0]) { + start_trace(0, + NULL, + NULL, + NULL, + DIRECTION_NONE, + 0, + 0, + "REMOTE APP release"); + add_trace("app", "name", "%s", admin->remote_name); + end_trace(); + /* release all exported channels */ + mISDNport = mISDNport_first; + while(mISDNport) + { + i = 0; + ii = mISDNport->b_num; + while(i < ii) + { + if (mISDNport->b_remote_id[i] == admin->sock) + { + mISDNport->b_state[i] = B_STATE_IDLE; + mISDNport->b_timer[i] = 0; + mISDNport->b_remote_id[i] = 0; + mISDNport->b_remote_ref[i] = 0; + } + i++; + } + mISDNport = mISDNport->next; + } + /* release join */ join = join_first; while(join) { @@ -144,6 +181,8 @@ void admin_cleanup(void) close(sock); fhuse--; } + + unlink(socket_name); } @@ -452,7 +491,7 @@ int admin_block(struct admin_queue **responsep, int portnum, int block) */ int admin_release(struct admin_queue **responsep, char *message) { - unsigned long id; + unsigned int id; struct admin_queue *response; /* response pointer */ class EndpointAppPBX *apppbx; @@ -579,39 +618,49 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i /* * send data to the remote socket join instance */ -int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) +int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin) { class Join *join; - struct admin_list *admin; + struct admin_list *temp; /* hello message */ if (msg->type == MESSAGE_HELLO) { - if (remote_name[0]) + if (admin->remote_name[0]) { PERROR("Remote application repeats hello message.\n"); return(-1); } /* look for second application */ - admin = admin_first; - while(admin) + temp = admin_first; + while(temp) { - if (!strcmp(admin->remote_name, msg->param.hello.application)) + if (!strcmp(temp->remote_name, msg->param.hello.application)) break; - admin = admin->next; + temp = temp->next; } - if (admin) + if (temp) { PERROR("Remote application connects twice??? (ignoring)\n"); return(-1); } /* set remote socket instance */ - SCPY(remote_name, msg->param.hello.application); + SCPY(admin->remote_name, msg->param.hello.application); + start_trace(0, + NULL, + NULL, + NULL, + DIRECTION_NONE, + 0, + 0, + "REMOTE APP registers"); + add_trace("app", "name", "%s", admin->remote_name); + end_trace(); return(0); } /* check we have no application name */ - if (remote_name[0]) + if (!admin->remote_name[0]) { PERROR("Remote application did not send us a hello message.\n"); return(-1); @@ -621,9 +670,12 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) if (msg->type == MESSAGE_NEWREF) { /* create new join instance */ - join = new JoinRemote(0, remote_name, sock_id); // must have no serial, because no endpoint is connected + join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected if (!join) + { FATAL("No memory for remote join instance\n"); + return(-1); + } return(0); } @@ -631,10 +683,11 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) * no ref given for *_ack */ if (msg->type == MESSAGE_BCHANNEL) if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK - || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK) + || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK + || msg->param.bchannel.type == BCHANNEL_RELEASE) { /* no ref, but address */ - message_bchannel_from_join(NULL, msg->param.bchannel.type, msg->param.bchannel.handle); + message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle); return(0); } @@ -655,8 +708,8 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) } if (!join) { - PERROR("No join found with serial %d.\n", msg->ref); - return(-1); + PDEBUG(DEBUG_LOG, "No join found with serial %d. (May have been already released.)\n", msg->ref); + return(0); } /* check application */ @@ -665,9 +718,9 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref); return(-1); } - if (sock_id != ((class JoinRemote *)join)->j_remote_id) + if (admin->sock != ((class JoinRemote *)join)->j_remote_id) { - PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, remote_name); + PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, admin->remote_name); return(-1); } @@ -681,10 +734,10 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) /* * this function is called for every message to remote socket */ -int admin_message_from_join(int remote_id, unsigned long ref, int message_type, union parameter *param) +int admin_message_from_join(int remote_id, unsigned int ref, int message_type, union parameter *param) { struct admin_list *admin; - struct admin_queue *response, **responsep; /* response pointer */ + struct admin_queue **responsep; /* response pointer */ /* searching for admin id * maybe there is no given remote application @@ -701,27 +754,22 @@ int admin_message_from_join(int remote_id, unsigned long ref, int message_type, return(-1); /* seek to end of response list */ - response = admin->response; responsep = &admin->response; - while(response) + while(*responsep) { - responsep = &response->next; - response = response->next; + responsep = &(*responsep)->next; } /* create state response */ - response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); + *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - response->num = 1; + (*responsep)->num = 1; /* message */ - response->am[0].u.msg.type = message_type; - response->am[0].u.msg.ref = ref; - memcpy(&response->am[0].u.msg.param, param, sizeof(union parameter)); - - /* attach to response chain */ - *responsep = response; - responsep = &response->next; + (*responsep)->am[0].message = ADMIN_MESSAGE; + (*responsep)->am[0].u.msg.type = message_type; + (*responsep)->am[0].u.msg.ref = ref; + memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter)); return(0); } @@ -813,8 +861,12 @@ int admin_state(struct admin_queue **responsep) *responsep = response; responsep = &response->next; - /* create response for all interfaces */ - num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.joins)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports); + /* create response for all instances */ + num = (response->am[0].u.s.interfaces) + + (response->am[0].u.s.remotes) + + (response->am[0].u.s.joins) + + (response->am[0].u.s.epoints) + + (response->am[0].u.s.ports); if (num == 0) return(0); response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message))); @@ -874,6 +926,7 @@ int admin_state(struct admin_queue **responsep) response->am[num].u.i.busy[i] = mISDNport->b_state[i]; if (mISDNport->b_port[i]) response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial; + response->am[num].u.i.mode[i] = mISDNport->b_mode[i]; i++; } } @@ -1075,7 +1128,7 @@ int admin_handle(void) int len; int new_sock; socklen_t sock_len = sizeof(sock_address); - unsigned long on = 1; + unsigned int on = 1; int work = 0; /* if work was done */ struct Endpoint *epoint; @@ -1169,7 +1222,7 @@ int admin_handle(void) continue; } /* process socket command */ - if (admin->response) + if (admin->response && msg.message != ADMIN_MESSAGE) { PERROR("Data from socket %d while sending response.\n", admin->sock); *adminp = admin->next; @@ -1236,7 +1289,7 @@ int admin_handle(void) break; case ADMIN_MESSAGE: - if (admin_message_to_join(&msg.u.msg, admin->remote_name, admin->sock) < 0) + if (admin_message_to_join(&msg.u.msg, admin) < 0) { PERROR("Failed to deliver message for socket %d.\n", admin->sock); goto response_error; @@ -1295,7 +1348,7 @@ int admin_handle(void) work = 1; if (len == 0) goto end; - if (len < (int)(sizeof(struct admin_message)*(admin->response->num)-admin->response->offset)) + if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) { admin->response->offset+=len; goto next;