void NBS_pollCb(void* pself, PollMgrEvt evt, struct pollfd* fd) { NBS self = (NBS)pself; switch (evt) { case PollMgrEvt_prepare: if (self->sockR == fd->fd) { fd->events |= POLLIN; } if (self->sockW == fd->fd && ((NBS_isDgram(self)) ? !DgramBuf_empty(self->dbufW) : !StreamBuf_empty(self->sbufW))) { fd->events |= POLLOUT; } break; case PollMgrEvt_result: if (fd->fd == self->sockR) { self->canR = fd->revents & POLLIN; if (self->canR) { if (self->dataArrivalCb != NULL) { (*(self->dataArrivalCb))(self->dataArrivalCbData, self); } } } if (fd->fd == self->sockW) { self->canW = fd->revents & POLLOUT; if (self->canW) NBS_deferredWrite(self); } break; case PollMgrEvt_error: self->error = true; break; } }
Link Link_ctorStream(NBS nbs) { if (NBS_isDgram(nbs)) return NULL; Link self = ALLOCSELF; self->nbs = nbs; self->ccnbor = CcnbOR_ctor(nbs); return self; }
void NBS_pushback(NBS self, void* data, size_t start, size_t len, SockAddr srcaddr) { if (NBS_isDgram(self)) { DgramBuf_prepend(self->dbufR, data, start, len, BufMode_own, srcaddr); } else { StreamBuf_prepend(self->sbufR, data, start, len, BufMode_own); } }
CcnbOR CcnbOR_ctor(NBS nbs) { if (NBS_isDgram(nbs)) return NULL; CcnbOR self = ALLOCSELF; self->nbs = nbs; self->rd = (struct ccn_skeleton_decoder*)calloc(1, sizeof(struct ccn_skeleton_decoder)); self->cbuf = ccn_charbuf_create(); return self; }
LMD LMD_ctor(NBS nbs, SockAddr localAddr, size_t mtu) { if (!NBS_isDgram(nbs)) return NULL; LMD self = ALLOCSELF; self->nbs = nbs; if (localAddr != NULL) self->localAddr = SockAddr_clone(localAddr); self->mtu = mtu; self->demux = hashtb_create(sizeof(LMDRec), NULL); return self; }
void NBS_write(NBS self, void* data, size_t start, size_t len, SockAddr dstaddr) { if (NBS_isDgram(self)) { if (D) printf("NBS_write dgram sockW: %d sockR: %d\n", self->sockW, self->sockR); DgramBuf_append(self->dbufW, data, start, len, BufMode_own, dstaddr); if (self->sock_type == SockType_BPF) { self->canW = true; NBS_deferredWrite(self); } } else { if (D) printf("NBS_write stream sockW: %d sockR: %d\n", self->sockW, self->sockR); StreamBuf_append(self->sbufW, data, start, len, BufMode_own); } }
NBS NBS_ctor(int sockR, int sockW, enum SocketType sock_type) { NBS self = ALLOCSELF; self->sock_type = sock_type; self->sockR = sockR; self->sockW = sockW; if (NBS_isDgram(self)) { self->dbufR = DgramBuf_ctor(); self->dbufW = DgramBuf_ctor(); } else { self->sbufR = StreamBuf_ctor(); self->sbufW = StreamBuf_ctor(); } return self; }
void NBS_dtor(NBS self) { NBS_pollDetach(self); if (NBS_isDgram(self)) { DgramBuf_dtor(self->dbufR); DgramBuf_dtor(self->dbufW); } else { StreamBuf_dtor(self->sbufR); StreamBuf_dtor(self->sbufW); } if (self->closeSock) { close(self->sockR); if (self->sockW != self->sockR) close(self->sockW); } free(self); }
size_t NBS_read(NBS self, void* buf, size_t count, SockAddr srcaddr) { void* data; size_t len; size_t pos = 0; if (NBS_isDgram(self)) { if (D) printf("NBS_read dgram sockW: %d sockR: %d\n", self->sockW, self->sockR); if (DgramBuf_get(self->dbufR, &data, &len, srcaddr)) { if (count < len) len = count; memcpy(buf, data, len); DgramBuf_consumeOne(self->dbufR); return len; } } else { if (D) printf("NBS_read stream sockW: %d sockR: %d\n", self->sockW, self->sockR); while (StreamBuf_get(self->sbufR, &data, &len) && pos < count) { if (D) printf("inside\n"); if (count - pos < len) len = count - pos; memcpy((uint8_t*)buf + pos, data, len); pos += len; StreamBuf_consume(self->sbufR, len); } } if (pos < count && self->canR) { #ifdef ENABLE_ETHER_BPF if ( self->sock_type == SockType_BPF ) { int res = 0; struct bpf_hdr* bpf_packet; struct ether_header* eh; if ( (res = read(self->sockR, buf, self->bpf_len)) > 0 ) { uint8_t* ptr = (uint8_t*)buf; while ( ptr < ((uint8_t*)buf + res) ) { bpf_packet = (struct bpf_hdr*)ptr; data = (uint8_t*)bpf_packet + bpf_packet->bh_hdrlen + sizeof(struct ether_header); int datalen = bpf_packet->bh_datalen - sizeof(struct ether_header); eh = (struct ether_header*)((uint8_t*)bpf_packet + bpf_packet->bh_hdrlen); uint8_t* sadll = ((struct sockaddr_ll*)(SockAddr_addr(srcaddr)))->sll_addr; memcpy(sadll, eh->ether_shost, sizeof(((struct sockaddr_ll*)(SockAddr_addr(srcaddr)))->sll_addr)); ((struct sockaddr_ll*)(SockAddr_addr(srcaddr)))->sll_family = AF_PACKET; ((struct sockaddr_ll*)(SockAddr_addr(srcaddr)))->sll_halen = 6; DgramBuf_append(self->dbufR, data, 0, datalen, BufMode_clone, srcaddr); ptr += BPF_WORDALIGN(bpf_packet->bh_hdrlen + bpf_packet->bh_caplen); } /* get first packet */ if (DgramBuf_get(self->dbufR, &data, &len, srcaddr)) { memcpy(buf, data, len); DgramBuf_consumeOne(self->dbufR); } } if (res == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) self->canR = false; else self->error = true; } else { pos += len; } return pos; } #endif // ENABLE_ETHER_BPF void* recvbuf = (uint8_t*)buf + pos; size_t recvbuflen = count - pos; ssize_t res; if (NBS_isDgram(self) && srcaddr != NULL) { res = recvfrom(self->sockR, recvbuf, recvbuflen, 0, SockAddr_addr(srcaddr), SockAddr_addrlenp(srcaddr)); } else { res = read(self->sockR, recvbuf, recvbuflen); } if (res == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) self->canR = false; else self->error = true; } else { pos += res; } return pos; } return 0; }