void sig_notify(int itf,int up) { SIGNALING_ENTITY *sig; for (sig = entities; sig; sig = sig->next) if (sig->itf == itf) break; if (!sig) { diag(COMPONENT,DIAG_ERROR,"%s notification for unknown interface %d", up ? "up" : "down",itf); return; } if (sig->pvc.sap_addr.itf == -1) return; if (up) { struct atm_qos qos; sig->call = new_call(); sig->call->in.pvc = sig->pvc; sig->call->out.pvc.sap_addr.itf = sig->itf; sig->call->out.pvc.sap_addr.vpi = 0; sig->call->out.pvc.sap_addr.vci = 5; memset(&qos,0,sizeof(qos)); qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR; fab_op(sig->call,RM_CLAIM(_RM_ANY),&qos,up_callback,sig); } else { route_sig(sig,&sig->call->out.pvc,0); remove_entity(sig); fab_op(sig->call,RM_FREE,NULL,down_callback,NULL); free_call(sig->call); } }
struct call *lac_call (int tid, struct lac *lac, struct lns *lns) { struct tunnel *t = tunnels.head; struct call *tmp; while (t) { if (t->ourtid == tid) { tmp = new_call (t); if (!tmp) { log (LOG_WARN, "%s: unable to create new call\n", __FUNCTION__); return NULL; } tmp->next = t->call_head; t->call_head = tmp; t->count++; tmp->cid = 0; tmp->lac = lac; tmp->lns = lns; if (lac) lac->c = tmp; log (LOG_NOTICE, "Calling on tunnel %d\n", tid); strcpy (tmp->dial_no, dial_no_tmp); /* jz: copy dialnumber to tmp->dial_no */ control_finish (t, tmp); return tmp; } t = t->next; }; log (LOG_DEBUG, "%s: No such tunnel %d to generate call.\n", __FUNCTION__, tid); return NULL; }
/* * This will be with every control message. It is critical that this * procedure check for the validity of sending this kind of a message * (assuming sanity check) */ int message_type_avp(struct tunnel *t, struct call *c, const struct avp *data, int datalen) { struct call *tmp; c->msgtype = ntohs(data->data.us); if (datalen != 8) { l2tp_log(LOG_DEBUG, "%s: wrong size (%d != 8)\n", __func__, datalen); wrong_length(c, "Message Type", 8, datalen, 0); return -EINVAL; } /* This is handled in sanity_failed now. May use it. */ if ((c->msgtype > MAX_MSG) || (!msgtypes[c->msgtype])) { l2tp_log(LOG_DEBUG, "%s: unknown message type %d\n", __func__, c->msgtype); return -EINVAL; } if (gconfig.debug_avp) l2tp_log(LOG_DEBUG, "%s: message type %d (%s)\n", __func__, c->msgtype, msgtypes[c->msgtype]); if (sanity_enabled(t) && mta_sanity_failed(t, c)) return -EINVAL; if (c->msgtype != ICRQ) return 0; if (gconfig.debug_avp) l2tp_log(LOG_DEBUG, "%s: new incoming call\n", __func__); tmp = new_call(t); if (!tmp) { l2tp_log(LOG_WARNING, "%s: unable to create new call\n", __func__); return -EINVAL; } tmp->next = t->call_head; t->call_head = tmp; t->count++; /* * Is this still safe to assume that the head will always * be the most recent call being negotiated? * Probably... FIXME anyway... */ return 0; }
void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) { LOGGER_DEBUG(m->log, "Got msi message"); MSISession *session = (MSISession *)object; MSIMessage msg; if (msg_parse_in(m->log, &msg, data, length) == -1) { LOGGER_WARNING(m->log, "Error parsing message"); send_error(m, friend_number, msi_EInvalidMessage); return; } LOGGER_DEBUG(m->log, "Successfully parsed message"); pthread_mutex_lock(session->mutex); MSICall *call = get_call(session, friend_number); if (call == NULL) { if (msg.request.value != requ_init) { send_error(m, friend_number, msi_EStrayMessage); pthread_mutex_unlock(session->mutex); return; } call = new_call(session, friend_number); if (call == NULL) { send_error(m, friend_number, msi_ESystem); pthread_mutex_unlock(session->mutex); return; } } switch (msg.request.value) { case requ_init: handle_init(call, &msg); break; case requ_push: handle_push(call, &msg); break; case requ_pop: handle_pop(call, &msg); /* always kills the call */ break; } pthread_mutex_unlock(session->mutex); }
struct tunnel *new_tunnel () { struct tunnel *tmp = calloc (1, sizeof (struct tunnel)); unsigned char entropy_buf[2] = "\0"; if (!tmp) return NULL; tmp->debug = 0; tmp->tid = -1; memset(&tmp->rt, 0, sizeof(tmp->rt)); #ifndef TESTING /* while(get_call((tmp->ourtid = rand() & 0xFFFF),0,0,0)); */ /* tmp->ourtid = rand () & 0xFFFF; */ /* get_entropy((char *)&tmp->ourtid, 2); */ get_entropy(entropy_buf, 2); { unsigned short *temp; temp = (unsigned short *)entropy_buf; tmp->ourtid = *temp & 0xFFFF; #ifdef DEBUG_ENTROPY l2tp_log(LOG_DEBUG, "ourtid = %u, entropy_buf = %hx\n", tmp->ourtid, *temp); #endif } #else tmp->ourtid = 0x6227; #endif tmp->peer.sin_family = AF_INET; bzero (&(tmp->peer.sin_addr), sizeof (tmp->peer.sin_addr)); #ifdef SANITY tmp->sanity = -1; #endif tmp->qtid = -1; tmp->ourfc = ASYNC_FRAMING | SYNC_FRAMING; tmp->ourtb = (((_u64) rand ()) << 32) | ((_u64) rand ()); tmp->fc = -1; /* These really need to be specified by the peer */ tmp->bc = -1; /* And we want to know if they forgot */ if (!(tmp->self = new_call (tmp))) { free (tmp); return NULL; }; tmp->ourrws = DEFAULT_RWS_SIZE; tmp->self->ourfbit = FBIT; tmp->rxspeed = DEFAULT_RX_BPS; tmp->txspeed = DEFAULT_TX_BPS; memset (tmp->chal_us.reply, 0, MD_SIG_SIZE); memset (tmp->chal_them.reply, 0, MD_SIG_SIZE); tmp->chal_them.vector = (unsigned char *) malloc (VECTOR_SIZE); return tmp; }
int messages_get_message(void *s, const char *h, unsigned long flags, messages_get_message_cb cb, void *user_data) { struct session *session = s; struct request *request; DBusPendingCall *call; int err = 0; char *handle = strip_handle(h); char *query_handle = g_strdup_printf(MESSAGES_FILTER_BY_HANDLE, handle); char *query = path2query("telecom/msg", LIST_MESSAGES_QUERY, query_handle); if (query == NULL) { err = -ENOENT; goto failed; } if (flags & MESSAGES_FRACTION || flags & MESSAGES_NEXT) { err = -EBADR; goto failed; } request = g_new0(struct request, 1); request->name = g_strdup(handle); request->flags = flags; request->cb.message = cb; request->generate_response = get_message_resp; request->user_data = user_data; session->aborted = FALSE; session->request = request; call = query_tracker(query, session, &err); if (err == 0) new_call(call); failed: g_free(query_handle); g_free(query); g_free(handle); return err; }
int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities) { if (!session) { return -1; } LOGGER_DEBUG(session->messenger->log, "Session: %p Inviting friend: %u", session, friend_number); if (pthread_mutex_trylock(session->mutex) != 0) { LOGGER_ERROR(session->messenger->log, "Failed to aquire lock on msi mutex"); return -1; } if (get_call(session, friend_number) != NULL) { LOGGER_ERROR(session->messenger->log, "Already in a call"); pthread_mutex_unlock(session->mutex); return -1; } (*call) = new_call(session, friend_number); if (*call == NULL) { pthread_mutex_unlock(session->mutex); return -1; } (*call)->self_capabilities = capabilities; MSIMessage msg; msg_init(&msg, requ_init); msg.capabilities.exists = true; msg.capabilities.value = capabilities; send_message((*call)->session->messenger, (*call)->friend_number, &msg); (*call)->state = msi_CallRequesting; LOGGER_DEBUG(session->messenger->log, "Invite sent"); pthread_mutex_unlock(session->mutex); return 0; }
struct tunnel *new_tunnel () { struct tunnel *tmp = malloc (sizeof (struct tunnel)); char entropy_buf[2] = "\0"; if (!tmp) return NULL; tmp->control_seq_num = 0; tmp->control_rec_seq_num = 0; tmp->cLr = 0; tmp->call_head = NULL; tmp->next = NULL; tmp->debug = -1; tmp->tid = -1; tmp->hello = NULL; #ifndef TESTING /* while(get_call((tmp->ourtid = rand() & 0xFFFF),0,0,0)); */ #ifdef USE_KERNEL if (kernel_support) tmp->ourtid = ioctl (server_socket, L2TPIOCADDTUNNEL, 0); else #endif /* tmp->ourtid = rand () & 0xFFFF; */ /* get_entropy((char *)&tmp->ourtid, 2); */ get_entropy(entropy_buf, 2); { unsigned short *temp; temp = (unsigned short *)entropy_buf; tmp->ourtid = *temp & 0xFFFF; #ifdef DEBUG_ENTROPY log(LOG_DEBUG, "ourtid = %u, entropy_buf = %hx\n", tmp->ourtid, *temp); #endif } #else tmp->ourtid = 0x6227; #endif tmp->nego = 0; tmp->count = 0; tmp->state = 0; /* Nothing */ tmp->peer.sin_family = AF_INET; tmp->peer.sin_port = 0; bzero (&(tmp->peer.sin_addr), sizeof (tmp->peer.sin_addr)); tmp->sanity = -1; tmp->qtid = -1; tmp->ourfc = ASYNC_FRAMING | SYNC_FRAMING; tmp->ourbc = 0; tmp->ourtb = (((_u64) rand ()) << 32) | ((_u64) rand ()); tmp->fc = -1; /* These really need to be specified by the peer */ tmp->bc = -1; /* And we want to know if they forgot */ tmp->hostname[0] = 0; tmp->vendor[0] = 0; tmp->secret[0] = 0; if (!(tmp->self = new_call (tmp))) { free (tmp); return NULL; }; tmp->ourrws = DEFAULT_RWS_SIZE; tmp->self->ourfbit = FBIT; tmp->lac = NULL; tmp->lns = NULL; tmp->chal_us.state = 0; tmp->chal_us.secret[0] = 0; memset (tmp->chal_us.reply, 0, MD_SIG_SIZE); tmp->chal_us.challenge = NULL; tmp->chal_us.chal_len = 0; tmp->chal_them.state = 0; tmp->chal_them.secret[0] = 0; memset (tmp->chal_them.reply, 0, MD_SIG_SIZE); tmp->chal_them.challenge = NULL; tmp->chal_them.chal_len = 0; tmp->chal_them.vector = (unsigned char *) malloc (VECTOR_SIZE); tmp->chal_us.vector = NULL; tmp->hbit = 0; return tmp; }
int messages_get_messages_listing(void *s, const char *name, uint16_t max, uint16_t offset, const struct messages_filter *filter, messages_get_messages_listing_cb callback, void *user_data) { struct session *session = s; struct request *request; char *path, *query; struct message_folder *folder = NULL; DBusPendingCall *call; int err = 0; if (name == NULL || strlen(name) == 0) { path = g_strdup(session->cwd); folder = session->folder; if (folder == NULL) folder = get_folder(path); } else { if (strchr(name, '/') != NULL) return -EBADR; path = g_build_filename(session->cwd, name, NULL); folder = get_folder(path); } g_free(path); if (folder == NULL) return -ENOENT; query = folder2query(folder, LIST_MESSAGES_QUERY); if (query == NULL) return -ENOENT; request = g_new0(struct request, 1); request->filter = copy_messages_filter(filter); request->generate_response = get_messages_listing_resp; request->cb.messages_list = callback; request->offset = offset; request->max = max; request->user_data = user_data; session->aborted = FALSE; session->request = request; if (max == 0) { request->max = 0xffff; request->offset = 0; request->count = TRUE; } call = query_tracker(query, session, &err); if (err == 0) new_call(call); g_free(query); return err; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_test_only_set_metadata_hash_seed(0); if (squelch) gpr_set_log_function(dont_log); input_stream inp = {data, data + size}; grpc_resolve_address = my_resolve_address; grpc_tcp_client_connect_impl = my_tcp_client_connect; gpr_now_impl = now_impl; grpc_init(); GPR_ASSERT(g_channel == NULL); GPR_ASSERT(g_server == NULL); bool server_shutdown = false; int pending_server_shutdowns = 0; int pending_channel_watches = 0; int pending_pings = 0; g_active_call = new_call(NULL, ROOT); grpc_completion_queue *cq = grpc_completion_queue_create(NULL); while (!is_eof(&inp) || g_channel != NULL || g_server != NULL || pending_channel_watches > 0 || pending_pings > 0 || g_active_call->type != ROOT || g_active_call->next != g_active_call) { if (is_eof(&inp)) { if (g_channel != NULL) { grpc_channel_destroy(g_channel); g_channel = NULL; } if (g_server != NULL) { if (!server_shutdown) { grpc_server_shutdown_and_notify( g_server, cq, create_validator(assert_success_and_decrement, &pending_server_shutdowns)); server_shutdown = true; pending_server_shutdowns++; } else if (pending_server_shutdowns == 0) { grpc_server_destroy(g_server); g_server = NULL; } } call_state *s = g_active_call; do { if (s->type != PENDING_SERVER && s->call != NULL) { s = destroy_call(s); } else { s = s->next; } } while (s != g_active_call); g_now = gpr_time_add(g_now, gpr_time_from_seconds(1, GPR_TIMESPAN)); } switch (next_byte(&inp)) { // terminate on bad bytes default: end(&inp); break; // tickle completion queue case 0: { grpc_event ev = grpc_completion_queue_next( cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL); switch (ev.type) { case GRPC_OP_COMPLETE: { validator *v = ev.tag; v->validate(v->arg, ev.success); gpr_free(v); break; } case GRPC_QUEUE_TIMEOUT: break; case GRPC_QUEUE_SHUTDOWN: abort(); break; } break; } // increment global time case 1: { g_now = gpr_time_add( g_now, gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); break; } // create an insecure channel case 2: { if (g_channel == NULL) { char *target = read_string(&inp); char *target_uri; gpr_asprintf(&target_uri, "dns:%s", target); grpc_channel_args *args = read_args(&inp); g_channel = grpc_insecure_channel_create(target_uri, args, NULL); GPR_ASSERT(g_channel != NULL); grpc_channel_args_destroy(args); gpr_free(target_uri); gpr_free(target); } else { end(&inp); } break; } // destroy a channel case 3: { if (g_channel != NULL) { grpc_channel_destroy(g_channel); g_channel = NULL; } else { end(&inp); } break; } // bring up a server case 4: { if (g_server == NULL) { grpc_channel_args *args = read_args(&inp); g_server = grpc_server_create(args, NULL); GPR_ASSERT(g_server != NULL); grpc_channel_args_destroy(args); grpc_server_register_completion_queue(g_server, cq, NULL); grpc_server_start(g_server); server_shutdown = false; GPR_ASSERT(pending_server_shutdowns == 0); } else { end(&inp); } } // begin server shutdown case 5: { if (g_server != NULL) { grpc_server_shutdown_and_notify( g_server, cq, create_validator(assert_success_and_decrement, &pending_server_shutdowns)); pending_server_shutdowns++; server_shutdown = true; } else { end(&inp); } break; } // cancel all calls if shutdown case 6: { if (g_server != NULL && server_shutdown) { grpc_server_cancel_all_calls(g_server); } else { end(&inp); } break; } // destroy server case 7: { if (g_server != NULL && server_shutdown && pending_server_shutdowns == 0) { grpc_server_destroy(g_server); g_server = NULL; } else { end(&inp); } break; } // check connectivity case 8: { if (g_channel != NULL) { uint8_t try_to_connect = next_byte(&inp); if (try_to_connect == 0 || try_to_connect == 1) { grpc_channel_check_connectivity_state(g_channel, try_to_connect); } else { end(&inp); } } else { end(&inp); } break; } // watch connectivity case 9: { if (g_channel != NULL) { grpc_connectivity_state st = grpc_channel_check_connectivity_state(g_channel, 0); if (st != GRPC_CHANNEL_FATAL_FAILURE) { gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); grpc_channel_watch_connectivity_state( g_channel, st, deadline, cq, create_validator(validate_connectivity_watch, make_connectivity_watch( deadline, &pending_channel_watches))); pending_channel_watches++; } } else { end(&inp); } break; } // create a call case 10: { bool ok = true; if (g_channel == NULL) ok = false; grpc_call *parent_call = NULL; if (g_active_call->type != ROOT) { if (g_active_call->call == NULL || g_active_call->type == CLIENT) { end(&inp); break; } parent_call = g_active_call->call; } uint32_t propagation_mask = read_uint32(&inp); char *method = read_string(&inp); char *host = read_string(&inp); gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); if (ok) { call_state *cs = new_call(g_active_call, CLIENT); cs->call = grpc_channel_create_call(g_channel, parent_call, propagation_mask, cq, method, host, deadline, NULL); } else { end(&inp); } gpr_free(method); gpr_free(host); break; } // switch the 'current' call case 11: { g_active_call = g_active_call->next; break; } // queue some ops on a call case 12: { if (g_active_call->type == PENDING_SERVER || g_active_call->type == ROOT || g_active_call->call == NULL) { end(&inp); break; } size_t num_ops = next_byte(&inp); if (num_ops > 6) { end(&inp); break; } grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops); bool ok = true; size_t i; grpc_op *op; for (i = 0; i < num_ops; i++) { op = &ops[i]; switch (next_byte(&inp)) { default: /* invalid value */ op->op = (grpc_op_type)-1; ok = false; break; case GRPC_OP_SEND_INITIAL_METADATA: op->op = GRPC_OP_SEND_INITIAL_METADATA; read_metadata(&inp, &op->data.send_initial_metadata.count, &op->data.send_initial_metadata.metadata, g_active_call); break; case GRPC_OP_SEND_MESSAGE: op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = read_message(&inp); break; case GRPC_OP_SEND_CLOSE_FROM_CLIENT: op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; break; case GRPC_OP_SEND_STATUS_FROM_SERVER: op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; read_metadata( &inp, &op->data.send_status_from_server.trailing_metadata_count, &op->data.send_status_from_server.trailing_metadata, g_active_call); op->data.send_status_from_server.status = next_byte(&inp); op->data.send_status_from_server.status_details = read_string(&inp); break; case GRPC_OP_RECV_INITIAL_METADATA: op->op = GRPC_OP_RECV_INITIAL_METADATA; op->data.recv_initial_metadata = &g_active_call->recv_initial_metadata; break; case GRPC_OP_RECV_MESSAGE: op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &g_active_call->recv_message; break; case GRPC_OP_RECV_STATUS_ON_CLIENT: op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.status = &g_active_call->status; op->data.recv_status_on_client.trailing_metadata = &g_active_call->recv_trailing_metadata; op->data.recv_status_on_client.status_details = &g_active_call->recv_status_details; op->data.recv_status_on_client.status_details_capacity = &g_active_call->recv_status_details_capacity; break; case GRPC_OP_RECV_CLOSE_ON_SERVER: op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->data.recv_close_on_server.cancelled = &g_active_call->cancelled; break; } op->reserved = NULL; op->flags = read_uint32(&inp); } if (ok) { validator *v = create_validator(finished_batch, g_active_call); g_active_call->pending_ops++; grpc_call_error error = grpc_call_start_batch(g_active_call->call, ops, num_ops, v, NULL); if (error != GRPC_CALL_OK) { v->validate(v->arg, false); gpr_free(v); } } else { end(&inp); } for (i = 0; i < num_ops; i++) { op = &ops[i]; switch (op->op) { case GRPC_OP_SEND_INITIAL_METADATA: break; case GRPC_OP_SEND_MESSAGE: grpc_byte_buffer_destroy(op->data.send_message); break; case GRPC_OP_SEND_STATUS_FROM_SERVER: gpr_free((void *)op->data.send_status_from_server.status_details); break; case GRPC_OP_SEND_CLOSE_FROM_CLIENT: case GRPC_OP_RECV_INITIAL_METADATA: case GRPC_OP_RECV_MESSAGE: case GRPC_OP_RECV_STATUS_ON_CLIENT: case GRPC_OP_RECV_CLOSE_ON_SERVER: break; } } gpr_free(ops); break; } // cancel current call case 13: { if (g_active_call->type != ROOT && g_active_call->call != NULL) { grpc_call_cancel(g_active_call->call, NULL); } else { end(&inp); } break; } // get a calls peer case 14: { if (g_active_call->type != ROOT && g_active_call->call != NULL) { free_non_null(grpc_call_get_peer(g_active_call->call)); } else { end(&inp); } break; } // get a channels target case 15: { if (g_channel != NULL) { free_non_null(grpc_channel_get_target(g_channel)); } else { end(&inp); } break; } // send a ping on a channel case 16: { if (g_channel != NULL) { pending_pings++; grpc_channel_ping(g_channel, cq, create_validator(decrement, &pending_pings), NULL); } else { end(&inp); } break; } // enable a tracer case 17: { char *tracer = read_string(&inp); grpc_tracer_set_enabled(tracer, 1); gpr_free(tracer); break; } // disable a tracer case 18: { char *tracer = read_string(&inp); grpc_tracer_set_enabled(tracer, 0); gpr_free(tracer); break; } // request a server call case 19: { if (g_server == NULL) { end(&inp); break; } call_state *cs = new_call(g_active_call, PENDING_SERVER); cs->pending_ops++; validator *v = create_validator(finished_request_call, cs); grpc_call_error error = grpc_server_request_call(g_server, &cs->call, &cs->call_details, &cs->recv_initial_metadata, cq, cq, v); if (error != GRPC_CALL_OK) { v->validate(v->arg, false); gpr_free(v); } break; } // destroy a call case 20: { if (g_active_call->type != ROOT && g_active_call->type != PENDING_SERVER && g_active_call->call != NULL) { destroy_call(g_active_call); } else { end(&inp); } break; } } } GPR_ASSERT(g_channel == NULL); GPR_ASSERT(g_server == NULL); GPR_ASSERT(g_active_call->type == ROOT); GPR_ASSERT(g_active_call->next == g_active_call); gpr_free(g_active_call); grpc_completion_queue_shutdown(cq); GPR_ASSERT( grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL) .type == GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(cq); grpc_shutdown(); return 0; }