static int rtp_data_bts(struct osmo_fd *fd, unsigned int what) { char buf[4096]; struct sockaddr_in addr; struct mgcp_endpoint *endp; int rc, proto; endp = (struct mgcp_endpoint *) fd->data; rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf)); if (rc <= 0) return -1; proto = fd == &endp->bts_end.rtp ? PROTO_RTP : PROTO_RTCP; /* We have no idea who called us, maybe it is the BTS. */ /* it was the BTS... */ discover_bts(endp, proto, &addr); if (memcmp(&endp->bts_end.addr, &addr.sin_addr, sizeof(addr.sin_addr)) != 0) { LOGP(DMGCP, LOGL_ERROR, "Data from wrong bts %s on 0x%x\n", inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(endp)); return -1; } if (endp->bts_end.rtp_port != addr.sin_port && endp->bts_end.rtcp_port != addr.sin_port) { LOGP(DMGCP, LOGL_ERROR, "Data from wrong bts source port %d on 0x%x\n", ntohs(addr.sin_port), ENDPOINT_NUMBER(endp)); return -1; } /* throw away the dummy message */ if (rc == 1 && buf[0] == DUMMY_LOAD) { LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from bts on 0x%x\n", ENDPOINT_NUMBER(endp)); return 0; } /* do this before the loop handling */ endp->bts_end.packets += 1; endp->bts_end.octets += rc; forward_data(fd->fd, &endp->taps[MGCP_TAP_BTS_IN], buf, rc); switch (endp->type) { case MGCP_RTP_DEFAULT: return send_to(endp, DEST_NETWORK, proto == PROTO_RTP, &addr, buf, rc); case MGCP_RTP_TRANSCODED: return send_transcoder(&endp->trans_bts, endp->cfg, proto == PROTO_RTP, buf, rc); } LOGP(DMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n", endp->type, ENDPOINT_NUMBER(endp)); return 0; }
static int rtp_data_net(struct osmo_fd *fd, unsigned int what) { char buf[4096]; struct sockaddr_in addr; struct mgcp_endpoint *endp; int rc, proto; endp = (struct mgcp_endpoint *) fd->data; rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf)); if (rc <= 0) return -1; if (memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) != 0) { LOGP(DMGCP, LOGL_ERROR, "Endpoint 0x%x data from wrong address %s vs. ", ENDPOINT_NUMBER(endp), inet_ntoa(addr.sin_addr)); LOGPC(DMGCP, LOGL_ERROR, "%s\n", inet_ntoa(endp->net_end.addr)); return -1; } if (endp->net_end.rtp_port != addr.sin_port && endp->net_end.rtcp_port != addr.sin_port) { LOGP(DMGCP, LOGL_ERROR, "Data from wrong source port %d on 0x%x\n", ntohs(addr.sin_port), ENDPOINT_NUMBER(endp)); return -1; } /* throw away the dummy message */ if (rc == 1 && buf[0] == DUMMY_LOAD) { LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from network on 0x%x\n", ENDPOINT_NUMBER(endp)); return 0; } proto = fd == &endp->net_end.rtp ? PROTO_RTP : PROTO_RTCP; endp->net_end.packets += 1; endp->net_end.octets += rc; forward_data(fd->fd, &endp->taps[MGCP_TAP_NET_IN], buf, rc); switch (endp->type) { case MGCP_RTP_DEFAULT: return send_to(endp, DEST_BTS, proto == PROTO_RTP, &addr, buf, rc); case MGCP_RTP_TRANSCODED: return send_transcoder(&endp->trans_net, endp->cfg, proto == PROTO_RTP, buf, rc); } LOGP(DMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n", endp->type, ENDPOINT_NUMBER(endp)); return 0; }
int CUdpSocket::receive_from(void* buffer, size_t buffer_size, uint32_t* from_ip, uint16_t* from_port) throw (sys::CSyscallException) { struct sockaddr_in from_addr; int bytes = receive_from(buffer, buffer_size, &from_addr); *from_ip = from_addr.sin_addr.s_addr; *from_port = ntohs(from_addr.sin_port); return bytes; }
int boss::Socket::receive_from(void *buf, size_t len, string & from_address, uint16_t & from_port, int flags) { struct sockaddr from; socklen_t fromlen = sizeof(struct sockaddr); struct sockaddr_in *p = (struct sockaddr_in *) &from; bzero(&from, sizeof(struct sockaddr)); int bytes = receive_from(buf, len, from, fromlen, flags); if (bytes < 0){ throw SocketException(_error_text); } char addr[INET_ADDRSTRLEN]; from_address = inet_ntop(AF_INET, &p->sin_addr, addr, sizeof(addr)); from_port = ntohs(p->sin_port); return bytes; }
static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp, int dest, struct osmo_fd *fd) { char buf[RTP_BUF_SIZE]; struct sockaddr_in addr; struct mgcp_config *cfg; int rc, proto; cfg = _endp->cfg; rc = receive_from(_endp, fd->fd, &addr, buf, sizeof(buf)); if (rc <= 0) return -1; proto = fd == &end->rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP; if (memcmp(&addr.sin_addr, &cfg->transcoder_in, sizeof(addr.sin_addr)) != 0) { LOGP(DMGCP, LOGL_ERROR, "Data not coming from transcoder dest: %d %s on 0x%x\n", dest, inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(_endp)); return -1; } if (end->rtp_port != addr.sin_port && end->rtcp_port != addr.sin_port) { LOGP(DMGCP, LOGL_ERROR, "Data from wrong transcoder dest %d source port %d on 0x%x\n", dest, ntohs(addr.sin_port), ENDPOINT_NUMBER(_endp)); return -1; } /* throw away the dummy message */ if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) { LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from transcoder dest %d on 0x%x\n", dest, ENDPOINT_NUMBER(_endp)); return 0; } end->packets += 1; return mgcp_send(_endp, dest, proto == MGCP_PROTO_RTP, &addr, buf, rc); }