struct tunnel *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns) { /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; struct in_addr addr; port = htons (port); hp = gethostbyname (host); if (!hp) { l2tp_log (LOG_WARNING, "Host name lookup failed for %s.\n", host); schedule_redial(lac); return NULL; } bcopy (hp->h_addr, &addr.s_addr, hp->h_length); /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* * to do IPsec properly here, we need to set a socket policy, * and/or communicate with pluto. */ tmp = get_call (0, 0, addr, port, IPSEC_SAREF_NULL, IPSEC_SAREF_NULL); if (!tmp) { l2tp_log (LOG_WARNING, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); schedule_redial(lac); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ l2tp_log (LOG_NOTICE, "Connecting to host %s, port %d\n", host, ntohs (port)); if (lac) { if (lac->route_rdgw == 1) route_add(tmp->container->peer.sin_addr, 0, &tmp->container->rt); else if (lac->route_rdgw == 2) route_add(tmp->container->peer.sin_addr, 1, &tmp->container->rt); } control_finish (tmp->container, tmp); return tmp->container; }
int msi_kill(MSISession *session, Logger *log) { if (session == NULL) { LOGGER_ERROR(log, "Tried to terminate non-existing session"); return -1; } m_callback_msi_packet((struct Messenger *) session->messenger, NULL, NULL); if (pthread_mutex_trylock(session->mutex) != 0) { LOGGER_ERROR(session->messenger->log, "Failed to aquire lock on msi mutex"); return -1; } if (session->calls) { MSIMessage msg; msg_init(&msg, requ_pop); MSICall *it = get_call(session, session->calls_head); while (it) { send_message(session->messenger, it->friend_number, &msg); MSICall *temp_it = it; it = it->next; kill_call(temp_it); /* This will eventually free session->calls */ } } pthread_mutex_unlock(session->mutex); pthread_mutex_destroy(session->mutex); LOGGER_DEBUG(session->messenger->log, "Terminated session: %p", session); free(session); return 0; }
void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data) { (void)m; MSISession *session = (MSISession *)data; switch (status) { case 0: { /* Friend is now offline */ LOGGER_DEBUG(m->log, "Friend %d is now offline", friend_number); pthread_mutex_lock(session->mutex); MSICall *call = get_call(session, friend_number); if (call == NULL) { pthread_mutex_unlock(session->mutex); return; } invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */ kill_call(call); pthread_mutex_unlock(session->mutex); } break; default: break; } }
/** Answer an IPC call. * * @param callid Hash of the call to be answered. * @param data Userspace address of call data with the answer. * * @return 0 on success, otherwise an error code. * */ sysarg_t sys_ipc_answer_slow(sysarg_t callid, ipc_data_t *data) { /* Do not answer notification callids */ if (callid & IPC_CALLID_NOTIFICATION) return 0; call_t *call = get_call(callid); if (!call) return ENOENT; ipc_data_t saved_data; bool saved; if (answer_need_old(call)) { memcpy(&saved_data, &call->data, sizeof(call->data)); saved = true; } else saved = false; int rc = copy_from_uspace(&call->data.args, &data->args, sizeof(call->data.args)); if (rc != 0) return rc; rc = answer_preprocess(call, saved ? &saved_data : NULL); ipc_answer(&TASK->answerbox, call); return rc; }
void log_pidcalls (void) { static unint interval = 0; Pidcall_s *pc; int pid; int i; int rc; if (!Fp) return; ++interval; for (i = 0; i < Num_rank; i++) { pc = Rank_pidcall[i]; pid = get_pid(pc->pidcall); if (!pc->name) { pc->name = get_exe_path(pid); } rc = fprintf(Fp, "%ld,%d,%d,%lld,%s,%s\n", interval, pid, pc->snap.count, pc->snap.total_time, Syscall[get_call(pc->pidcall)], pc->name); if (rc < 0) { warn("Log failed %s:", File); log_close(); } } }
struct tunnel *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns) { /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; struct in_addr addr; #if !defined(__UCLIBC__) \ || (__UCLIBC_MAJOR__ == 0 \ && (__UCLIBC_MINOR__ < 9 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 31))) /* force ns refresh from resolv.conf with uClibc pre-0.9.31 */ res_init(); #endif port = htons (port); hp = gethostbyname (host); if (!hp) { l2tp_log (LOG_WARNING, "Host name lookup failed for %s.\n", host); return NULL; } bcopy (hp->h_addr, &addr.s_addr, hp->h_length); /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* * to do IPsec properly here, we need to set a socket policy, * and/or communicate with pluto. */ tmp = get_call (0, 0, addr, port, IPSEC_SAREF_NULL, IPSEC_SAREF_NULL); if (!tmp) { l2tp_log (LOG_WARNING, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ l2tp_log (LOG_NOTICE, "Connecting to host %s, port %d\n", host, ntohs (port)); control_finish (tmp->container, tmp); return tmp->container; }
bool call_handler::add_button() { button* btn_in = new button(this->_floor_count+1); if(!btn_in) return false; this->_buttons_in.push_back(btn_in); connect(btn_in,SIGNAL(signal_Pressed(size_t)),this,SLOT(get_call(size_t))); this->_floor_count++; return true; }
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 *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns) { /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; unsigned int addr; port = htons (port); hp = gethostbyname (host); if (!hp) { log (LOG_WARN, "Host name lookup failed for %s.\n", host); return NULL; } bcopy (hp->h_addr, &addr, hp->h_length); /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* XXX L2TP/IPSec: Set up SA to addr:port here? NTB 20011010 */ tmp = get_call (0, 0, addr, port); if (!tmp) { log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ log (LOG_NOTICE, "Connecting to host %s, port %d\n", host, ntohs (port)); control_finish (tmp->container, tmp); return tmp->container; }
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; }
/** Answer an IPC call - fast version. * * This function can handle only two return arguments of payload, but is faster * than the generic sys_ipc_answer(). * * @param callid Hash of the call to be answered. * @param retval Return value of the answer. * @param arg1 Service-defined return value. * @param arg2 Service-defined return value. * @param arg3 Service-defined return value. * @param arg4 Service-defined return value. * * @return 0 on success, otherwise an error code. * */ sysarg_t sys_ipc_answer_fast(sysarg_t callid, sysarg_t retval, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) { /* Do not answer notification callids */ if (callid & IPC_CALLID_NOTIFICATION) return 0; call_t *call = get_call(callid); if (!call) return ENOENT; ipc_data_t saved_data; bool saved; if (answer_need_old(call)) { memcpy(&saved_data, &call->data, sizeof(call->data)); saved = true; } else saved = false; IPC_SET_RETVAL(call->data, retval); IPC_SET_ARG1(call->data, arg1); IPC_SET_ARG2(call->data, arg2); IPC_SET_ARG3(call->data, arg3); IPC_SET_ARG4(call->data, arg4); /* * To achieve deterministic behavior, zero out arguments that are beyond * the limits of the fast version. */ IPC_SET_ARG5(call->data, 0); int rc = answer_preprocess(call, saved ? &saved_data : NULL); ipc_answer(&TASK->answerbox, call); return rc; }
struct tunnel *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns) { /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; unsigned int addr; //------------------------------------------------- #if defined(CONFIG_RTL8186_TR) || defined(CONFIG_RTL865X_SC) struct in_addr retval; struct in_addr intaddr; struct in_addr intmask; char server_ip[100]; char l2tp_gw[30]; char l2tp_ipdyn[30]; char cmdBuffer[200]; FILE *fp1, *fp2; #endif //------------------------------------------------ port = htons (port); hp = gethostbyname (host); if (!hp) { log (LOG_WARN, "Host name lookup failed for %s.\n", host); return NULL; } #if defined(CONFIG_RTL8186_TR) || defined(CONFIG_RTL865X_SC) //Brad add //if l2tp server is not in the same subnet as l2tp client, we put l2tp server ip to /var/l2tp_server memcpy(&retval.s_addr, hp->h_addr, sizeof(retval.s_addr)); if (getInAddr("eth1", IP_ADDR, (void *)&intaddr )){ if(getInAddr("eth1", SUBNET_MASK, (void *)&intmask)){ if((intaddr.s_addr & intmask.s_addr) != (retval.s_addr & intmask.s_addr)){ //warn("generate pptp server =%s\n", inet_ntoa(retval)); sprintf(server_ip, "echo %s > /var/l2tp_server", inet_ntoa(retval)); system(server_ip); fp1= fopen("/var/l2tp_dyn", "r"); if(fp1 !=NULL){ fscanf(fp1, "%s", l2tp_ipdyn); if(l2tp_ipdyn[0]=='1'){ fp2= fopen("/var/l2tp_gw", "r"); if (fp2 != NULL) { fscanf(fp2, "%s", l2tp_gw); sprintf(cmdBuffer, "route add -host %s gw %s", inet_ntoa(retval), l2tp_gw); system(cmdBuffer); fclose(fp2); } }else{ fp2= fopen("/var/eth1_gw", "r"); if (fp2 != NULL) { fscanf(fp2, "%s", l2tp_gw); sprintf(cmdBuffer, "route add -host %s gw %s", inet_ntoa(retval), l2tp_gw); system(cmdBuffer); fclose(fp2); } } fclose(fp1); } } } } #endif bcopy (hp->h_addr, &addr, hp->h_length); /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* XXX L2TP/IPSec: Set up SA to addr:port here? NTB 20011010 */ tmp = get_call (0, 0, addr, port); if (!tmp) { log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ log (LOG_NOTICE, "Connecting to host %s, port %d\n", host, ntohs (port)); control_finish (tmp->container, tmp); return tmp->container; }
int main(int argc, char **argv) { int i, j, fd, curfile, chars, k, in_comment = 0, in_white = 0, calls = 0, in_parens = 0, in_quotes = 0, in_define = 0, in_curly = 0; int maxc[NAME_SIZE], maxf[NAME_SIZE], maxg[NAME_SIZE], mcalls[NAME_SIZE]; qdata **qs; char input[MAX_CHARS]; char curname[ID_SIZE]; FILE *FD = NULL; names_size = NAME_SIZE; names = (char **)calloc(names_size, sizeof(char *)); hnames = (char **)calloc(names_size, sizeof(char *)); nnames = (char **)calloc(names_size, sizeof(char *)); voids = (int *)calloc(names_size, sizeof(int)); files_size = 256; files = (char **)calloc(files_size, sizeof(char *)); headers_size = 32; headers = (char **)calloc(headers_size, sizeof(char *)); counts = (int **)calloc(names_size, sizeof(int *)); lines = (char ***)calloc(names_size, sizeof(char **)); results = (int *)calloc(names_size, sizeof(int)); procs = (int *)calloc(names_size, sizeof(int)); add_header("sndlib.h"); add_header("clm.h"); add_header("vct.h"); add_header("sndlib2xen.h"); add_header("clm2xen.h"); add_header("snd.h"); #if 1 add_header("snd-strings.h"); add_header("sndlib-strings.h"); add_header("clm-strings.h"); #endif add_header("snd-0.h"); add_header("snd-1.h"); add_header("snd-x0.h"); add_header("snd-x1.h"); add_header("snd-g0.h"); add_header("snd-g1.h"); add_header("snd-nogui0.h"); add_header("snd-nogui1.h"); add_header("snd-rec.h"); add_header("xen.h"); add_header("mus-config.h.in"); add_header("libclm.def"); add_header("snd-menu.h"); add_header("snd-file.h"); /* add_file("xen.h"); */ /* add_file("snd.h"); */ add_file("headers.c"); add_file("audio.c"); add_file("io.c"); add_file("sound.c"); add_file("clm.c"); add_file("vct.c"); add_file("cmus.c"); add_file("sndlib2xen.c"); add_file("clm2xen.c"); add_file("midi.c"); add_file("snd-io.c"); add_file("snd-utils.c"); add_file("snd-error.c"); add_file("snd-completion.c"); add_file("snd-menu.c"); add_file("snd-axis.c"); add_file("snd-data.c"); add_file("snd-draw.c"); add_file("snd-fft.c"); add_file("snd-marks.c"); add_file("snd-file.c"); add_file("snd-edits.c"); add_file("snd-chn.c"); add_file("snd-sig.c"); add_file("snd-kbd.c"); add_file("snd-dac.c"); add_file("snd-region.c"); add_file("snd-run.c"); add_file("snd-select.c"); add_file("snd-find.c"); add_file("snd-snd.c"); add_file("snd-help.c"); add_file("snd-main.c"); add_file("snd-print.c"); add_file("snd-trans.c"); add_file("snd-mix.c"); add_file("snd.c"); add_file("snd-rec.c"); add_file("snd-env.c"); add_file("snd-xen.c"); add_file("snd-ladspa.c"); add_file("snd-xutils.c"); add_file("snd-xhelp.c"); add_file("snd-xfind.c"); add_file("snd-xmenu.c"); add_file("snd-xdraw.c"); add_file("snd-xlistener.c"); add_file("snd-listener.c"); add_file("snd-xchn.c"); add_file("snd-xsnd.c"); add_file("snd-xregion.c"); add_file("snd-xdrop.c"); add_file("snd-xmain.c"); add_file("snd-xmix.c"); add_file("snd-xrec.c"); add_file("snd-xenv.c"); add_file("snd-gxutils.c"); add_file("snd-gxbitmaps.c"); add_file("snd-gxcolormaps.c"); add_file("snd-xfft.c"); add_file("snd-xprint.c"); add_file("snd-xfile.c"); add_file("snd-xprefs.c"); add_file("snd-xxen.c"); add_file("snd-gutils.c"); add_file("snd-ghelp.c"); add_file("snd-gfind.c"); add_file("snd-gmenu.c"); add_file("snd-gdraw.c"); add_file("snd-glistener.c"); add_file("snd-gchn.c"); add_file("snd-gsnd.c"); add_file("snd-gregion.c"); add_file("snd-gdrop.c"); add_file("snd-gmain.c"); add_file("snd-gmix.c"); add_file("snd-grec.c"); add_file("snd-genv.c"); add_file("snd-gxutils.c"); add_file("snd-gfft.c"); add_file("snd-gprint.c"); add_file("snd-gfile.c"); add_file("snd-gxen.c"); add_file("snd-gprefs.c"); add_file("snd-prefs.c"); add_file("snd-nogui.c"); add_file("xen.c"); add_file("xm.c"); add_file("gl.c"); add_file("xg.c"); add_file("cmus.c"); add_file("sc.c"); add_file("ffi.lisp"); add_file("sndlib2clm.lisp"); for (i = 0; i < headers_ctr; i++) { k = 0; in_quotes = 0; in_white = 0; in_parens = 0; in_comment = 0; fd = open(headers[i], O_RDONLY, 0); if (fd == -1) fprintf(stderr, "can't find %s\n", headers[i]); else { do { chars = read(fd, input, MAX_CHARS); /* fprintf(stderr,"%s %d ", headers[i], chars); */ for (j = 0; j < chars; j++) { if ((in_comment == 0) && (in_curly == 0)) { if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_')) { in_white = 0; if (k < ID_SIZE) curname[k++] = input[j]; else fprintf(stderr, "0: curname overflow: %s[%d]: %s%c\n", headers[i], j, curname, input[j]); } else { in_white = 1; if (k < ID_SIZE) curname[k] = 0; else fprintf(stderr, "1: curname overflow: %s[%d]: %s\n", headers[i], j, curname); if ((k > 0) && (in_parens == 0) && (in_quotes == 0)) { int loc; loc = add_name(copy_string(curname), headers[i]); if (loc >= 0) { int start, n, maybe_proc = 1; for (n = 0; n < k; n++) if (isupper(curname[n])) { maybe_proc = 0; break; } if ((maybe_proc) && ((input[j] == '(') || ((input[j] == ' ') && (input[j + 1] == '(')))) procs[loc] = maybe_proc; else procs[loc] = 0; start = j - strlen(curname) - 6; if (start >= 0) { int m; for (m = 0; m < 3; m++) if (strncmp((char *)(input + start + m), "void", 4) == 0) { voids[loc] = 1; break; } } } } /* else if (k > 0) fprintf(stderr,"drop %s %d %d\n",curname,in_parens, in_quotes); */ k = 0; if ((input[j] == '/') && (input[j + 1] == '*')) in_comment = 1; else { if (input[j] == '#') in_define = 1; else { if ((input[j] == '{') && ((j < 6) || (strncmp((input + (j - 5)), "enum", 4) != 0))) in_curly = 1; else { if (input[j] == '(') in_parens++; if (input[j] == ')') in_parens--; if (input[j] == '"') { if (in_quotes == 1) in_quotes = 0; else in_quotes = 1; } } } } } } else /* in comment or curly */ { if ((input[j] == '*') && (input[j + 1] == '/')) in_comment = 0; else { if (input[j] == '}') in_curly = 2; else { if (input[j] == ';') in_curly = 0; } } } } } while (chars == MAX_CHARS); close(fd); } } fprintf(stderr, "%d names ", names_ctr); k = 0; in_comment = 0; in_white = 0; in_define = 0; for (i = 0; i < files_ctr; i++) { k = 0; fd = open(files[i], O_RDONLY, 0); if (fd == -1) fprintf(stderr, "can't find %s\n", files[i]); else { int curly_ctr = 0,cancel_define = 0; in_define = 0; if ((strcmp(files[i], "sndlib2clm.lisp") == 0) || (strcmp(files[i], "ffi.lisp") == 0)) curly_ctr = 1; do { chars = read(fd, input, MAX_CHARS); /* fprintf(stderr,"%s %d\n", files[i], chars); */ for (j = 0; j < chars; j++) { if (in_comment == 0) { if ((isalpha(input[j])) || (isdigit(input[j])) || (input[j] == '_')) { if (k < ID_SIZE) curname[k++] = input[j]; else fprintf(stderr, "2: curname overflow: %s[%d]: %s\n", files[i], j, curname); } else { if ((input[j] == '/') && (input[j + 1] == '*')) in_comment = 1; else { if ((input[j] == '#') && (input[j + 1] == 'd')) { /* int m; fprintf(stderr,"def..."); for (m = j; (m < j + 16) && (m < chars); m++) fprintf(stderr,"%c", input[m]); */ in_define = 1; } else { if ((in_define == 1) && (input[j] == '\n') && (j > 0) && (input[j - 1] != '\\')) { /* fprintf(stderr,"!\n"); */ cancel_define = 1; } } if ((in_define == 0) && (j < (chars - 1)) && ((input[j - 1] != '\'') || (input[j + 1] != '\''))) { if (input[j] == '{') curly_ctr++; else if (input[j] == '}') curly_ctr--; } } if (k > 0) { if (k < ID_SIZE) curname[k] = 0; else fprintf(stderr, "3: curname overflow: %s[%d]: %s\n", files[i], j, curname); if ((k < ID_SIZE) && ((curly_ctr > 0) || (in_define == 1))) { int loc; loc = add_count(curname, i); if (loc >= 0) { if (procs[loc]) results[loc] += get_result(input, j, k); if (lines[loc] == NULL) { lines[loc] = (char **)calloc(MAX_LINES, sizeof(char *)); lines[loc][0] = get_call(input, j, k, curname, chars); } else { int m; for (m = 0; m < MAX_LINES; m++) if (lines[loc][m] == NULL) { lines[loc][m] = get_call(input, j, k, curname, chars); break; } } } } k = 0; } if (cancel_define == 1) { cancel_define = 0; in_define = 0; } } } else { if ((input[j] == '*') && (input[j + 1] == '/')) in_comment = 0; } } } while (chars == MAX_CHARS); close(fd); } } FD = fopen("xref.data","w"); if (!FD) fprintf(stderr, "can't write xref.data?"); else { for (i = 0; i < names_ctr; i++) { maxc[i] = 0; maxf[i] = 0; maxg[i] = 0; for (j = 0; j < files_ctr; j++) if ((counts[i]) && (counts[i][j] > 0)) { maxc[i] += counts[i][j]; maxf[i]++; if ((j == snd_xen_c) || (j == snd_nogui_c)) maxg[i]++; } } for (i = 0; i < names_ctr; i++) { calls = 0; if (counts[i]) for (j = 0; j < files_ctr; j++) calls += counts[i][j]; mcalls[i] = calls; } qs = (qdata **)calloc(NAME_SIZE, sizeof(qdata *)); for (i = 0; i < names_ctr; i++) { qdata *q; q = calloc(1, sizeof(qdata)); qs[i] = q; q->i = i; q->v = voids[i]; q->name = names[i]; q->hname = hnames[i]; q->calls = mcalls[i]; q->results = results[i]; q->proc = procs[i]; } qsort((void *)qs, names_ctr, sizeof(qdata *), greater_compare); for (i = 0; i < names_ctr; i++) { bool menu_case = false, file_case = false, rec_case = false, nonogui_case = false; int menu_count = 0, file_count = 0, rec_count = 0; int nfiles; nfiles = 0; /* try to get rid of a bunch of annoying false positives */ if ((qs[i]->calls == 0) && ((strcmp(qs[i]->hname, "xen.h") == 0) || (strcmp(qs[i]->hname, "mus-config.h.in") == 0) || (qs[i]->name[strlen(qs[i]->name) - 2] == '_') && ((qs[i]->name[strlen(qs[i]->name) - 1] == 't') || (qs[i]->name[strlen(qs[i]->name) - 1] == 'H')))) { } else { fprintf(FD, "\n\n%s: %d [%s]", qs[i]->name, qs[i]->calls, qs[i]->hname); if (qs[i]->v) { fprintf(FD, " (void)"); } else { if ((qs[i]->results == 0) && (qs[i]->proc > 0) && (qs[i]->calls > 0) && (strncmp(qs[i]->name, "set_", 4) != 0) && (strncmp(qs[i]->name, "in_set_", 7) != 0)) fprintf(FD, " (not void but result not used?)"); } menu_case = (strcmp(qs[i]->hname, "snd-menu.h") != 0); file_case = (strcmp(qs[i]->hname, "snd-file.h") != 0); rec_case = (strcmp(qs[i]->hname, "snd-rec.h") != 0); menu_count = 0; file_count = 0; rec_count = 0; nonogui_case = in_nogui_h(qs[i]->name); if ((nonogui_case) && (counts[qs[i]->i])) { /* fprintf(stderr, "%s...", qs[i]->name); */ for (j = 0; j < files_ctr; j++) if ((counts[qs[i]->i][j] > 0) && ((strcmp(files[j], "snd-xen.c") == 0) || ((strcmp(files[j], "snd-nogui.c") != 0) && (strncmp(files[j], "snd-x", 5) != 0) && (strncmp(files[j], "snd-g", 5) != 0)))) { /* fprintf(stderr,"in %s\n", files[j]); */ nonogui_case = false; break; } /* if (nonogui_case) fprintf(stderr, "!\n"); */ } for (j = 0; j < files_ctr; j++) { if ((counts[qs[i]->i]) && (counts[qs[i]->i][j] > 0)) { if (menu_case) { if ((strcmp(files[j], "snd-menu.c") != 0) && (strcmp(files[j], "snd-xmenu.c") != 0) && (strcmp(files[j], "snd-gmenu.c") != 0)) { if (strcmp(files[j], "snd-nogui.c") != 0) menu_case = false; } else menu_count++; } if (file_case) { if ((strcmp(files[j], "snd-file.c") != 0) && (strcmp(files[j], "snd-xfile.c") != 0) && (strcmp(files[j], "snd-gfile.c") != 0)) { if (strcmp(files[j], "snd-nogui.c") != 0) file_case = false; } else file_count++; } if (rec_case) { if ((strcmp(files[j], "snd-rec.c") != 0) && (strcmp(files[j], "snd-xrec.c") != 0) && (strcmp(files[j], "snd-grec.c") != 0)) { if (strcmp(files[j], "snd-nogui.c") != 0) rec_case = false; } else rec_count++; } fprintf(FD,"\n %s: %d", files[j], counts[qs[i]->i][j]); nfiles++; } } if ((menu_case) && (menu_count > 0)) fprintf(FD, "\n->SND-MENU.H\n"); if ((file_case) && (file_count > 0)) fprintf(FD, "\n->SND-FILE.H\n"); if ((rec_case) && (rec_count > 0)) fprintf(FD, "\n->SND-REC.H\n"); if (nonogui_case) fprintf(FD, "\nnot needed in snd-nogui?\n"); { int m; if ((nfiles > 0) && (lines[qs[i]->i])) { fprintf(FD, "\n"); for (m = 0; m < MAX_LINES; m++) { if (lines[qs[i]->i][m] == NULL) break; fprintf(FD, "\n %s", lines[qs[i]->i][m]); } } } if ((nfiles < 2) && (qs[i]->calls > 1) && (islower(qs[i]->name[0])) && (strncmp(qs[i]->name, "snd_K", 5) != 0) && (strncmp(qs[i]->name, "mus_", 4) != 0) && (strncmp(qs[i]->name, "ps_", 3) != 0)) fprintf(FD, "\n----------------- (static?) -----------------------"); else fprintf(FD, "\n----------------"); } } fclose(FD); } return(0); }
struct tunnel *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns) { /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; unsigned int addr; FILE *fp; port = htons (port); /* Foxconn, added by MJ. 01/29/2010 */ struct in_addr l2tp_serv_ip; /* add routing for DNS server 01/29/2010*/ fxc_add_gw(1, l2tp_serv_ip); /* Foxconn, added end.*/ hp = gethostbyname (host); if (!hp) { log (LOG_WARN, "%s: gethostbyname() failed for %s.\n", __FUNCTION__, host); return NULL; } bcopy (hp->h_addr, &addr, hp->h_length); /* Foxconn, add start by MJ., for l2tp. 01/28/2010 */ if (hp->h_addrtype == AF_INET){ memcpy(&l2tp_serv_ip.s_addr, hp->h_addr, sizeof(l2tp_serv_ip.s_addr)); if ( fp = fopen("/tmp/ppp/l2tpSrvIp", "w") ) { fprintf(fp, "%s", inet_ntoa(l2tp_serv_ip)); fclose(fp); } } /* Add routing for L2TP server */ fxc_add_gw(2, l2tp_serv_ip); /* Foxconn, add end, by MJ., for l2tp. 01/28/2010 */ /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* XXX L2TP/IPSec: Set up SA to addr:port here? NTB 20011010 */ tmp = get_call (0, 0, addr, port); if (!tmp) { log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ log (LOG_LOG, "%s:Connecting to host %s, port %d\n", __FUNCTION__, host, ntohs (port)); control_finish (tmp->container, tmp); return tmp->container; }
/** Forward a received call to another destination * * Common code for both the fast and the slow version. * * @param callid Hash of the call to forward. * @param phoneid Phone handle to use for forwarding. * @param imethod New interface and method to use for the forwarded call. * @param arg1 New value of the first argument for the forwarded call. * @param arg2 New value of the second argument for the forwarded call. * @param arg3 New value of the third argument for the forwarded call. * @param arg4 New value of the fourth argument for the forwarded call. * @param arg5 New value of the fifth argument for the forwarded call. * @param mode Flags that specify mode of the forward operation. * @param slow If true, arg3, arg4 and arg5 are considered. Otherwise * the function considers only the fast version arguments: * i.e. arg1 and arg2. * * @return 0 on succes, otherwise an error code. * * Warning: Make sure that ARG5 is not rewritten for certain system IPC * */ static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phoneid, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow) { call_t *call = get_call(callid); phone_t *phone; bool need_old = answer_need_old(call); bool after_forward = false; ipc_data_t old; int rc; if (!call) return ENOENT; if (need_old) old = call->data; if (phone_get(phoneid, &phone) != EOK) { rc = ENOENT; goto error; } if (!method_is_forwardable(IPC_GET_IMETHOD(call->data))) { rc = EPERM; goto error; } call->flags |= IPC_CALL_FORWARDED; /* * User space is not allowed to change interface and method of system * methods on forward, allow changing ARG1, ARG2, ARG3 and ARG4 by * means of imethod, arg1, arg2 and arg3. * If the interface and method is immutable, don't change anything. */ if (!method_is_immutable(IPC_GET_IMETHOD(call->data))) { if (method_is_system(IPC_GET_IMETHOD(call->data))) { if (IPC_GET_IMETHOD(call->data) == IPC_M_CONNECT_TO_ME) phone_dealloc(IPC_GET_ARG5(call->data)); IPC_SET_ARG1(call->data, imethod); IPC_SET_ARG2(call->data, arg1); IPC_SET_ARG3(call->data, arg2); if (slow) IPC_SET_ARG4(call->data, arg3); /* * For system methods we deliberately don't * overwrite ARG5. */ } else { IPC_SET_IMETHOD(call->data, imethod); IPC_SET_ARG1(call->data, arg1); IPC_SET_ARG2(call->data, arg2); if (slow) { IPC_SET_ARG3(call->data, arg3); IPC_SET_ARG4(call->data, arg4); IPC_SET_ARG5(call->data, arg5); } } } rc = ipc_forward(call, phone, &TASK->answerbox, mode); if (rc != EOK) { after_forward = true; goto error; } return EOK; error: IPC_SET_RETVAL(call->data, EFORWARD); (void) answer_preprocess(call, need_old ? &old : NULL); if (after_forward) _ipc_answer_free_call(call, false); else ipc_answer(&TASK->answerbox, call); return rc; }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ struct sockaddr_in from; struct in_pktinfo to; unsigned int fromlen; int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv, *ptv; /* Timeout for select */ struct msghdr msgh; struct iovec iov; char cbuf[256]; unsigned int refme, refhim; int * currentfd; int server_socket_processed; #ifdef HIGH_PRIO /* set high priority */ if (setpriority(PRIO_PROCESS, 0, -20) < 0) l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m"); #endif /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); tunnel = 0; call = 0; for (;;) { int ret; process_signal(); max = build_fdset (&readfds); ptv = process_schedule(&tv); ret = select (max + 1, &readfds, NULL, NULL, ptv); if (ret <= 0) { #ifdef DEBUG_MORE if (ret == 0) { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__); } } else { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } } #endif continue; } if (FD_ISSET (control_fd, &readfds)) { do_control (); } server_socket_processed = 0; currentfd = NULL; st = tunnels.head; while (st || !server_socket_processed) { if (st && (st->udp_fd == -1)) { st=st->next; continue; } if (st) { currentfd = &st->udp_fd; } else { currentfd = &server_socket; server_socket_processed = 1; } if (FD_ISSET (*currentfd, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); fromlen = sizeof(from); memset(&msgh, 0, sizeof(struct msghdr)); iov.iov_base = buf->start; iov.iov_len = buf->len; msgh.msg_control = cbuf; msgh.msg_controllen = sizeof(cbuf); msgh.msg_name = &from; msgh.msg_namelen = fromlen; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; msgh.msg_flags = 0; /* Receive one packet. */ recvsize = recvmsg(*currentfd, &msgh, 0); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno == ECONNREFUSED) { close(*currentfd); } if ((errno == ECONNREFUSED) || (errno == EBADF)) { *currentfd = -1; } if (errno != EAGAIN) l2tp_log (LOG_WARNING, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { l2tp_log (LOG_WARNING, "%s: received too small a packet\n", __FUNCTION__); } if (st) st=st->next; continue; } refme=refhim=0; struct cmsghdr *cmsg; /* Process auxiliary received data in msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { /* extract destination(our) addr */ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg)); to = *pktInfo; } /* extract IPsec info out */ else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == gconfig.sarefnum) { unsigned int *refp; refp = (unsigned int *)CMSG_DATA(cmsg); refme =refp[0]; refhim=refp[1]; } } /* * some logic could be added here to verify that we only * get L2TP packets inside of IPsec, or to provide different * classes of service to packets not inside of IPsec. */ buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (gconfig.debug_network) { l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d ref=%u refhim=%u\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call, refme, refhim); } if (gconfig.packet_dump) { do_packet_dump (buf); } if (!(c = get_call (tunnel, call, from.sin_addr, from.sin_port, refme, refhim))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To * prevent this from closing the tunnel, if we get a * call on a valid tunnel, but not with a valid CID, * we'll just send a ZLB to ack receiving the packet. */ if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__, call, tunnel); if (handle_special (buf, c, call) == 0) /* get a new buffer */ buf = new_buf (MAX_RECV_SIZE); } #ifdef DEBUG_MORE else{ l2tp_log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } #endif } else { if (c->container) { c->container->my_addr = to; } buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); } if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } if (st) st=st->next; } /* * finished obvious sources, look for data from PPP connections. */ st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; while ((result = read_packet (sc)) > 0) { add_payload_hdr (sc->container, sc, sc->ppp_buf); if (gconfig.packet_dump) { do_packet_dump (sc->ppp_buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += sc->ppp_buf->len; sc->tx_pkts++; udp_xmit (sc->ppp_buf, st); recycle_payload (sc->ppp_buf, sc->container->peer); } if (result != 0) { l2tp_log (LOG_WARNING, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ struct sockaddr_in from, to; unsigned int fromlen, tolen; int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv, *ptv; /* Timeout for select */ struct msghdr msgh; struct iovec iov; char cbuf[256]; unsigned int refme, refhim; /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); tunnel = 0; call = 0; for (;;) { int ret; process_signal(); max = build_fdset (&readfds); ptv = process_schedule(&tv); ret = select (max + 1, &readfds, NULL, NULL, ptv); if (ret <= 0) { if (ret == 0) { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__); } } else { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } } continue; } if (FD_ISSET (control_fd, &readfds)) { do_control (); } if (FD_ISSET (server_socket, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); fromlen = sizeof(from); tolen = sizeof(to); memset(&msgh, 0, sizeof(struct msghdr)); iov.iov_base = buf->start; iov.iov_len = buf->len; msgh.msg_control = cbuf; msgh.msg_controllen = sizeof(cbuf); msgh.msg_name = &from; msgh.msg_namelen = fromlen; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; msgh.msg_flags = 0; /* Receive one packet. */ recvsize = recvmsg(server_socket, &msgh, 0); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) l2tp_log (LOG_WARNING, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { l2tp_log (LOG_WARNING, "%s: received too small a packet\n", __FUNCTION__); } continue; } refme=refhim=0; /* extract IPsec info out */ if(gconfig.ipsecsaref) { struct cmsghdr *cmsg; /* Process auxiliary received data in msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_IPSEC_REFINFO) { unsigned int *refp; refp = (unsigned int *)CMSG_DATA(cmsg); refme =refp[0]; refhim=refp[1]; } } } /* * some logic could be added here to verify that we only * get L2TP packets inside of IPsec, or to provide different * classes of service to packets not inside of IPsec. */ buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (gconfig.debug_network) { l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d ref=%u refhim=%u\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call, refme, refhim); } if (gconfig.packet_dump) { do_packet_dump (buf); } if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port, refme, refhim))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To * prevent this from closing the tunnel, if we get a * call on a valid tunnel, but not with a valid CID, * we'll just send a ZLB to ack receiving the packet. */ if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); /* get a new buffer */ buf = new_buf (MAX_RECV_SIZE); } else l2tp_log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } }; } /* * finished obvious sources, look for data from PPP connections. */ st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); /* #ifdef DEBUG_FLOW_MORE l2tp_log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf, st); recycle_payload (buf, sc->container->peer); } if (result != 0) { l2tp_log (LOG_WARNING, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ int fromlen; /* Length of the address */ int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv; /* Timeout for select */ /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); for (;;) { /* * First, let's send out any outgoing packets that are waiting on us. * xmit_udp should only * contain control packets in the unthreaded version! */ max = 0; FD_ZERO (&readfds); st = tunnels.head; while (st) { if (st->self->needclose ^ st->self->closing) { if (debug_tunnel) log (LOG_DEBUG, "%S: closing down tunnel %d\n", __FUNCTION__, st->ourtid); call_close (st->self); /* Reset the while loop and check for NULL */ st = tunnels.head; if (!st) break; continue; } sc = st->call_head; while (sc) { if (sc->needclose ^ sc->closing) { call_close (sc); sc = st->call_head; if (!sc) break; continue; } if (sc->fd > -1) { /* if (!sc->throttle && !sc->needclose && !sc->closing) { */ if (!sc->needclose && !sc->closing) { if (sc->fd > max) max = sc->fd; FD_SET (sc->fd, &readfds); } } sc = sc->next; } st = st->next; } FD_SET (server_socket, &readfds); if (server_socket > max) max = server_socket; FD_SET (control_fd, &readfds); if (control_fd > max) max = control_fd; tv.tv_sec = 1; tv.tv_usec = 0; /*add start, by MJ.*/ extern int is_first_run; if(is_first_run) { int lac_fp; /* to get conn_id which written by acos */ char cmd[64]={0}; char conn_id[64] = "c default"; lac_fp = fopen("/tmp/l2tp/l2tpd.info", "r"); if (lac_fp != NULL){ //fscanf(lac_fp, "%s", conn_id); fgets(conn_id, sizeof(conn_id), lac_fp); fclose(lac_fp); } else log (LOG_DEBUG, "open /tmp/l2tp/l2tpd.info fialed\n"); log (LOG_DEBUG, "%s: -> the first run.\n", __FUNCTION__); sprintf(cmd, "c %s", conn_id); //do_control("c MJ."); do_control(cmd); //write(control_fd, cmd, strlen(cmd) ); is_first_run = 0; } /*add end. by MJ.*/ schedule_unlock (); select (max + 1, &readfds, NULL, NULL, NULL); schedule_lock (); if (FD_ISSET (control_fd, &readfds)) { do_control (NULL); } if (FD_ISSET (server_socket, &readfds)) { /* wklin added start, 04/12/2011 */ extern void connect_pppunit(void); connect_pppunit(); /* wklin added end, 04/12/2011 */ /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; fromlen = sizeof (from); recvsize = recvfrom (server_socket, buf->start, buf->len, 0, (struct sockaddr *) &from, &fromlen); /* , by MJ. for debugging.*/ //log (LOG_DEBUG, "receive %d bytes from server_scoket.\n", recvsize); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) log (LOG_WARN, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { log (LOG_WARN, "%s: received too small a packet\n", __FUNCTION__); } } else { buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (debug_network) { log (LOG_DEBUG, "%s: recv packet from %s, size = %d," "tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (packet_dump) { do_packet_dump (buf); } if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To prevent * this from closing the tunnel, if we get a call on a valid * tunnel, but not with a valid CID, we'll just send a ZLB * to ack receiving the packet. */ if (debug_tunnel) log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); } else log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (debug_tunnel) log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } }; st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf); recycle_payload (buf, sc->container->peer); } if (result != 0) { log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ int fromlen; /* Length of the address */ int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv; /* Timeout for select */ /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); gconfig.debug_tunnel = 1; for (;;) { max = build_fdset (&readfds); tv.tv_sec = 1; tv.tv_usec = 0; schedule_unlock (); select (max + 1, &readfds, NULL, NULL, NULL); schedule_lock (); if (FD_ISSET (control_fd, &readfds)) { do_control (); } if (FD_ISSET (server_socket, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; fromlen = sizeof (from); recvsize = recvfrom (server_socket, buf->start, buf->len, 0, (struct sockaddr *) &from, &fromlen); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) log (LOG_WARN, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { log (LOG_WARN, "%s: received too small a packet\n", __FUNCTION__); } } else { buf->len = recvsize; if (gconfig.debug_network) { log (LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (gconfig.packet_dump) { do_packet_dump (buf); } fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port))) { log(LOG_DEBUG, "%s(%d)\n", __FUNCTION__,__LINE__); if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To prevent * this from closing the tunnel, if we get a call on a valid * tunnel, but not with a valid CID, we'll just send a ZLB * to ack receiving the packet. */ if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); } else log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s(%d): bad packet\n", __FUNCTION__,__LINE__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } }; st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf); recycle_payload (buf, sc->container->peer); } if (result != 0) { log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }