?? smsc_fake.c
字號(hào):
/* * Actually no quarantee of it having been really sent, * but I suppose that doesn't matter since this interface * is just for debugging anyway */ bb_smscconn_sent(conn, msg, NULL); } else { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED")); goto error; } /* obey throughput speed limit, if any */ if (conn->throughput > 0) { gwthread_sleep(delay); } } if (privdata->shutdown) { debug("bb.sms", 0, "smsc_fake shutting down, closing client socket"); conn_destroy(client); return; } conn_wait(client, -1); if (conn_error(client)) goto error; if (conn_eof(client)) goto eof; }error: info(0, "IO error to fakesmsc client. Closing connection."); conn_destroy(client); return;eof: info(0, "EOF from fakesmsc client. Closing connection."); conn_destroy(client); return;}static void fake_listener(void *arg){ SMSCConn *conn = arg; PrivData *privdata = conn->data; struct sockaddr_in client_addr; socklen_t client_addr_len; Octstr *ip; Connection *client; int s, ret; Msg *msg; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while (1) { client_addr_len = sizeof(client_addr); ret = gwthread_pollfd(privdata->listening_socket, POLLIN, -1); if (ret == -1) { if (errno == EINTR) continue; error(0, "Poll for fakesmsc connections failed, shutting down"); break; } if (privdata->shutdown) break; if (ret == 0) /* * This thread was woken up from elsewhere, but * if we're not shutting down nothing to do here. */ continue; s = accept(privdata->listening_socket, (struct sockaddr *)&client_addr, &client_addr_len); if (s == -1) { warning(errno, "fake_listener: accept() failed, retrying..."); continue; } ip = host_ip(client_addr); if (!is_allowed_ip(privdata->allow_ip, privdata->deny_ip, ip)) { info(0, "Fakesmsc connection tried from denied host <%s>," " disconnected", octstr_get_cstr(ip)); octstr_destroy(ip); close(s); continue; } client = conn_wrap_fd(s, 0); if (client == NULL) { error(0, "fake_listener: conn_wrap_fd failed on accept()ed fd"); octstr_destroy(ip); close(s); continue; } conn_claim(client); info(0, "Fakesmsc client connected from %s", octstr_get_cstr(ip)); octstr_destroy(ip); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; conn->connect_time = time(NULL); mutex_unlock(conn->flow_mutex); bb_smscconn_connected(conn); main_connection_loop(conn, client); if (privdata->shutdown) break; mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); } } if (close(privdata->listening_socket) == -1) warning(errno, "smsc_fake: couldn't close listening socket at shutdown"); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } gwlist_destroy(privdata->outgoing_queue, NULL); octstr_destroy(privdata->allow_ip); octstr_destroy(privdata->deny_ip); gw_free(privdata); conn->data = NULL; mutex_unlock(conn->flow_mutex); debug("bb.sms", 0, "smsc_fake connection has completed shutdown."); bb_smscconn_killed();}static int add_msg_cb(SMSCConn *conn, Msg *sms){ PrivData *privdata = conn->data; Msg *copy; copy = msg_duplicate(sms); gwlist_produce(privdata->outgoing_queue, copy); /* * Send DLR if desired, which means first add the DLR entry * and then later find it and remove it */ if (DLR_IS_ENABLED_DEVICE(sms->sms.dlr_mask)) { Octstr *tmp; char id[UUID_STR_LEN + 1]; uuid_unparse(sms->sms.id, id); tmp = octstr_format("%s", id); dlr_add(conn->id, tmp, sms); octstr_destroy(tmp); } gwthread_wakeup(privdata->connection_thread); return 0;}static int shutdown_cb(SMSCConn *conn, int finish_sending){ PrivData *privdata = conn->data; debug("bb.sms", 0, "Shutting down SMSCConn FAKE, %s", finish_sending ? "slow" : "instant"); /* * Documentation claims this would have been done by smscconn.c, * but isn't when this code is being written. */ conn->why_killed = SMSCCONN_KILLED_SHUTDOWN; privdata->shutdown = 1; /* * Separate from why_killed to avoid locking, as * why_killed may be changed from outside? */ if (finish_sending == 0) { Msg *msg; while((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } } gwthread_wakeup(privdata->connection_thread); return 0;}static void start_cb(SMSCConn *conn){ PrivData *privdata = conn->data; /* in case there are messages in the buffer already */ gwthread_wakeup(privdata->connection_thread); debug("bb.sms", 0, "smsc_fake: start called");}static long queued_cb(SMSCConn *conn){ PrivData *privdata = conn->data; long ret; ret = (privdata ? gwlist_len(privdata->outgoing_queue) : 0); /* use internal queue as load, maybe something else later */ conn->load = ret; return ret;}int smsc_fake_create(SMSCConn *conn, CfgGroup *cfg){ PrivData *privdata = NULL; Octstr *allow_ip, *deny_ip; long portno; /* has to be long because of cfg_get_integer */ if (cfg_get_integer(&portno, cfg, octstr_imm("port")) == -1) portno = 0; allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip")); if (allow_ip) deny_ip = octstr_create("*.*.*.*"); else deny_ip = NULL; if (portno == 0) { error(0, "'port' invalid in 'fake' record."); goto error; } privdata = gw_malloc(sizeof(PrivData)); privdata->listening_socket = -1; privdata->port = portno; privdata->allow_ip = allow_ip; privdata->deny_ip = deny_ip; if (fake_open_connection(conn, privdata) < 0) { gw_free(privdata); privdata = NULL; goto error; } conn->data = privdata; conn->name = octstr_format("FAKE:%d", privdata->port); privdata->outgoing_queue = gwlist_create(); privdata->shutdown = 0; conn->status = SMSCCONN_CONNECTING; conn->connect_time = time(NULL); if ((privdata->connection_thread = gwthread_create(fake_listener, conn)) == -1) goto error; conn->shutdown = shutdown_cb; conn->queued = queued_cb; conn->start_conn = start_cb; conn->send_msg = add_msg_cb; return 0;error: error(0, "Failed to create fake smsc connection"); if (privdata != NULL) { gwlist_destroy(privdata->outgoing_queue, NULL); if (close(privdata->listening_socket == -1)) { error(errno, "smsc_fake: closing listening socket port %d failed", privdata->listening_socket); } } gw_free(privdata); octstr_destroy(allow_ip); octstr_destroy(deny_ip); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; return -1;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -