📄 brocas.c
字号:
static intxq_transmit(struct xq_t *xq){ int flags = 0; int err = SENDTO(xq->xq_so, xq->xq_buf, xq->xq_size, flags, &xq->xq_saddr.sa, sizeof(xq->xq_saddr.sin)); if (err < 0) error("sendto"); if (debug_flag & 2) warning("xq_xmit(%p %lu)\n", xq, xq->xq_id); return err;}/* xq_transmit */static int xq_givenup;/* * 500msec 髓に钙び叫される、タイマル〖チン。 */static voidxq_timers(void){ struct xq_t *xq = xq_base; while (xq != NULL) { if (!xq->xq_givenup) { if (--(xq->xq_keep) == 0) { /* あきらめる。 */ xq->xq_givenup = 1; if (xq_givenup++ == 0) call_cback(BRO_EV_START_WORK_PROC, NULL); } else if (--(xq->xq_rexmt) == 0) { /* 浩流慨する。 */ xq_transmit(xq); xq->xq_rexmt0 = xq->xq_rexmt0 * 3 / 2; xq->xq_rexmt = xq->xq_rexmt0; } } xq = xq->xq_next; }/* while */}/* xq_timers *//* * */static voidxq_work_proc(void){ if (xq_givenup) { struct xq_t *xq = xq_base; while (xq != NULL) { struct xq_t *next = xq->xq_next; if (xq->xq_givenup) { char lbuf[64], *p; size_t size; memset(lbuf, '\0', sizeof(lbuf)); sprintf(lbuf, "%16s.%d ", inet_ntoa(xq->xq_saddr.sin.sin_addr), ntohs(xq->xq_saddr.sin.sin_port)); p = strchr(lbuf, '\0'); size = sizeof(lbuf) - (p - lbuf); memcpy(p, xq->xq_buf, MIN(xq->xq_size, size - 1)); call_cback(BRO_EV_NO_ACK, lbuf); xq_deq(xq); free(xq->xq_buf); free(xq); } xq = next; }/* while */ xq_givenup = 0; }}/* xq_work_proc *//* ] パケット浩流慨 */static size_tiov_total(const struct iov_t *v){ size_t total = 0; while (v != NULL) { total += v->iov_len; v = v->iov_next; }/* while */ return total;}/* iov_total */static void *iov_gather(void *buf_, const struct iov_t *v){ char *buf = buf_; while (v != NULL) { memcpy(buf, v->iov_base, v->iov_len); buf += v->iov_len; v = v->iov_next; }/* while */ return buf_;}/* iov_gather *//* * */static intp_sendtov(int so, const union saddr *to, unsigned long pno, const struct iov_t *iov){ int err = -1; struct xq_t *xq = malloc(sizeof(*xq)); if (xq != NULL) { size_t total = iov_total(iov); char *buf = malloc(total); if (buf != NULL) { iov_gather(buf, iov); xq_initone(xq); xq->xq_id = pno; xq->xq_so = so; xq->xq_saddr = *to; xq->xq_buf = buf; xq->xq_size = total; err = xq_transmit(xq); if (err >= 0) xq_enq(xq); else { free(xq->xq_buf); free(xq); } } } return err;}/* p_sendtov *//* * ソケット so からパケットを减慨する。 */static ssize_tp_get(int so, union saddr *from, int msec, void *buf, size_t size){ ssize_t err; struct timeval tv; fd_set readfds; FD_ZERO(&readfds); FD_SET(so, &readfds); tv.tv_sec = msec / 1000; tv.tv_usec = (msec % 1000) * 1000; err = select(so + 1, &readfds, NULL, NULL, &tv); if (err > 0) { int flags = 0, fromlen = sizeof(from->sa); err = recvfrom(so, buf, size, flags, &from->sa, &fromlen); if (err < 0) perror("recvfrom"); } return err;}/* p_get */static ssize_tsendtov(int so, int flags, const struct sockaddr *to, int tolen, const struct iov_t *iov){ ssize_t err = -1; size_t total = iov_total(iov); char *buf = malloc(total); if (buf != NULL) { iov_gather(buf, iov); err = SENDTO(so, buf, total, flags, to, tolen); if (err < 0) error("sendto"); free(buf); } return err;}/* sendtov */static unsigned long msg_number;static intsend_msgv(int so, const union saddr *to, unsigned long command, int retryflag, const struct iov_t *iov){ char lbuf[2 + 12 + USERNAME_MAX + 1 + HOSTNAME_MAX + 1 + 12]; int err, flags = 0; struct iov_t v; sprintf(lbuf, "1:%ld:%.*s:%.*s:%lu:", msg_number++, USERNAME_MAX, bro_user, HOSTNAME_MAX, bro_host, command); SET_IOV(&v, (void *)iov, lbuf, strlen(lbuf)); if (retryflag) { err = p_sendtov(so, to, msg_number - 1, &v); } else { err = sendtov(so, flags, &to->sa, sizeof(to->sin), &v); } return err;}/* send_msgv */static intsend_msg(int so, const union saddr *to, unsigned long command, const char *msg){ char lbuf[2 + 12 + USERNAME_MAX + 1 + HOSTNAME_MAX + 1 + 12]; int err, flags = 0; struct iov_t v[2]; sprintf(lbuf, "1:%ld:%.*s:%.*s:%lu:", msg_number++, USERNAME_MAX, bro_user, HOSTNAME_MAX, bro_host, command); SET_IOV(&v[0], &v[1], lbuf, strlen(lbuf)); SET_IOV(&v[1], NULL, (void *)msg, strlen(msg) + 1); err = sendtov(so, flags, &to->sa, sizeof(to->sin), v); return err;}/* send_msg *//* */intbro_send(const char *msg, const unsigned char *icon, const struct maddr_t *ma){ int err = -1; char *sjis = malloc(strlen(msg) + 1); if (sjis != NULL) { unsigned long cmd = IPMSG_SENDMSG | IPMSG_SENDCHECKOPT; int retry = 1; struct iov_t v[2]; stretos(sjis, msg); SET_IOV(&v[0], &v[1], sjis, strlen(sjis) + 1); SET_IOV(&v[1], NULL, (void *)icon, 128); if (send_msgv(ma->m_so, &ma->m_saddr, cmd, retry, v) > 0) err = 0; free(sjis); } return err;}/* bro_send *//* * 叹涟リストの瓷妄 [ */struct dyns_t STRUCT_DYNA(struct ns_t);struct dyns_t dyns;/* * INET ソケットアドレスの络井孺秤 */static intcmp_sin(const struct sockaddr_in *d, const struct sockaddr_in *s){ unsigned long da = d->sin_addr.s_addr, sa = s->sin_addr.s_addr; int cmp = da == sa ? 0 : (da < sa ? -1 : 1);#if 0 /* port 戎规は孺秤滦据としない */ if (cmp == 0) { cmp = ntohs(d->sin_port) - ntohs(s->sin_port); }#endif return cmp;}/* cmp_sin *//* * */static intns_cmp(const void *d_, const void *s_){ const struct ns_t *d = d_, *s = s_; const struct maddr_t *dm = &d->ns_maddr, *sm = &s->ns_maddr; int cmp = strcmpi(dm->m_user, sm->m_user); if (cmp == 0) { cmp = cmp_sin(&dm->m_saddr.sin, &sm->m_saddr.sin); } return cmp;}/* ns_cmp *//* * 叹涟リストから浮瑚する */struct ns_t *ns_lookup(const struct maddr_t *ma){ struct ns_t *ret = NULL; struct ns_t *ls = DYNA_BUF(&dyns); if (ls != NULL) { int n = DYNA_USED(&dyns); struct ns_t key; key.ns_maddr = *ma; ret = bsearch(&key, ls, n, sizeof(*ls), ns_cmp); } return ret;}/* ns_lookup *//* * */struct ns_t *ns_get(int idx){ struct ns_t *ret = NULL; struct ns_t *ls = DYNA_BUF(&dyns); if (ls != NULL) { int n = DYNA_USED(&dyns); if (idx >= 0 && idx < n) ret = &ls[idx]; } return ret;}/* ns_get *//* * 糠しいエントリを侯る。 */static struct ns_t *ns_new(const struct maddr_t *ma){ struct ns_t *ret = DYNA_NEXT(&dyns); if (ret != NULL) { struct ns_t key; struct ns_t *ls = DYNA_BUF(&dyns); int i = 0, n = DYNA_USED(&dyns) - 1; key.ns_maddr = *ma; while (i < n && ns_cmp(&key, &ls[i]) > 0) { i++; }/* while */ memmove(&ls[i + 1], &ls[i], sizeof(*ls) * (n - i)); ret = &ls[i]; memset(ret, '\0', sizeof(*ret)); } return ret;}/* ns_new *//* * */voidns_free(const struct maddr_t *ma){ struct ns_t *ns = ns_lookup(ma); if (ns != NULL) { struct ns_t *ls = DYNA_BUF(&dyns); int i = ns - ls, n = DYNA_USED(&dyns); memmove(&ls[i], &ls[i + 1], sizeof(*ls) * (n - i - 1)); DYNA_UNGROW(&dyns, 1); }}/* ns_free *//* * */voidns_clear(void){ DYNA_RESET(&dyns);}/* ns_clear *//* * */char **ns_list(void){ int n = DYNA_USED(&dyns); static char **last; char **ls = malloc(sizeof(*ls) * (n + 1)); if (last != NULL) { char **mv = last; while (*mv != NULL) free(*mv++); free(last); last = NULL; } if (ls != NULL) { int i; struct ns_t *ns = DYNA_BUF(&dyns); for (i = 0; i < n; i++, ns++) { size_t len = strlen(ns->ns_nick) + 1 + strlen(ns->ns_host); ls[i] = malloc(len + 1); if (ls[i] != NULL) { strcat(strcat(strcpy(ls[i], ns->ns_nick), "@"), ns->ns_host); } }/* for */ ls[n] = NULL; } last = ls; return ls;}/* ns_list *//* ] 叹涟リストの瓷妄 *//* * 票办パケットのフィルタリング [ * * 叹涟リストのエントリ髓に减慨パケットリストを积つ。 * 呵も呵夺减慨したパケットがリストの黎片にくるようにする。 * 减慨稿办年箕粗沸ったらリストから猴近する。 */#define RCV_KEEP (60*2) /* 瘦积する箕粗 [tic] *//* * パケット戎规 id が减慨リストにあるかどうか拇べる。 */static intrcv_id_lookup(struct rcv_t *rcv, unsigned long id){ int idx = 0; struct rcv_q_t *q = rcv->rcv_q; while (idx < rcv->rcv_used && q[idx].q_id != id) idx++; if (idx >= rcv->rcv_used) idx = -1; return idx;}/* rcv_id_lookup *//* * パケット戎规 id と、瘦积する箕粗を减慨リストに淡峡する。 */static intrcv_add(struct rcv_t *rcv, unsigned long id){ int err = -1; struct rcv_q_t *q = rcv->rcv_q; size_t size = rcv->rcv_size; if (rcv->rcv_used >= size) { size = size == 0 ? 64 : size * 2; q = realloc(q, size); if (q != NULL) { rcv->rcv_q = q; rcv->rcv_size = size; } } if (q != NULL) { memmove(q + 1, q, sizeof(*q) * rcv->rcv_used); rcv->rcv_used++; q->q_keep = bro_tic + RCV_KEEP; q->q_id = id; if (debug_flag & 2) warning("add: %lu %lu\n", q->q_id, q->q_keep); err = 0; } return err;}/* rcv_add *//* * パケット戎规 id をリストの黎片に败瓢する。 */static intrcv_raise(struct rcv_t *rcv, unsigned long id){ int i = rcv_id_lookup(rcv, id); if (i >= 0) { struct rcv_q_t *q = rcv->rcv_q; struct rcv_q_t x = q[i]; memmove(&q[1], q, i); *q = x; q->q_keep = bro_tic + RCV_KEEP; if (debug_flag & 2) warning("raise: %lu %lu\n", q->q_id, q->q_keep); } return 0;}/* rcv_raise *//* * 办年箕粗沸ったものは猴近する。 */static intrcv_delete(struct rcv_t *rcv){ struct rcv_q_t *q = rcv->rcv_q; int i = rcv->rcv_used; while (--i >= 0 && q[i].q_keep < bro_tic) if (debug_flag & 2) warning("delete: %lu %lu %lu\n", bro_tic, q[i].q_keep, q[i].q_id); i++; if (i + 1 < rcv->rcv_used) memmove(&q[i], &q[i + 1], sizeof(*q) * (rcv->rcv_used - (i + 1))); rcv->rcv_used = i; return 0;}/* rcv_delete *//* ] 票办パケットのフィルタリング *//* * ネットワ〖クの判峡 */struct dynet_t STRUCT_DYNA(union saddr);struct dynet_t dynet;static intnetwork_add(const char *broad){ union saddr *net; net = DYNA_NEXT(&dynet);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -