}
-int Channel::SendTo (evutil_socket_t sock, const Address& addr, struct evbuffer *evb) {
+int Channel::SendTo (evutil_socket_t sock, const Address& addr, struct evbuffer **evb) {
- int length = evbuffer_get_length(evb);
- int addr_len = sizeof(struct sockaddr_mptp) + addr.addr->count * sizeof(struct mptp_dest);
- struct iovec iov[1];
+ int count = addr.addr->count;
+ int addr_len = sizeof(struct sockaddr_mptp) + count * sizeof(struct mptp_dest);
+ struct iovec iov[count];
+ int lengths[count];
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
memset(&iov, 0, sizeof(iov));
- iov[0].iov_base = evbuffer_pullup(evb, length);
- iov[0].iov_len = length;
+ for (int i=0; i<count; ++i) {
+ lengths[i] = evbuffer_get_length(evb[i]);
+ iov[i].iov_base = evbuffer_pullup(evb[i], lengths[i]);
+ iov[i].iov_len = lengths[i];
+ }
msg.msg_iov = iov;
- msg.msg_iovlen = 1;
+ msg.msg_iovlen = count;
msg.msg_name = addr.addr;
msg.msg_namelen = addr_len;
int r = sendmsg(sock, &msg, 0);
if (r<0) {
print_error("can't send");
- evbuffer_drain(evb, length); // Arno: behaviour is to pretend the packet got lost
+ for (int i=0; i<count; ++i)
+ evbuffer_drain(evb[i], lengths[i]); // Arno: behaviour is to pretend the packet got lost
}
else
- evbuffer_drain(evb,r);
- global_dgrams_up++;
- global_raw_bytes_up+=length;
+ for (int i=0; i<count; ++i)
+ evbuffer_drain(evb[i], addr.addr->dests[i].bytes);
+ global_dgrams_up+=count;
+ for (int i=0; i<count; ++i)
+ global_raw_bytes_up+=lengths[i];
Time();
return r;
}
dprintf("%s #%u sent %ib %s:%x\n",
tintstr(),id_,(int)evbuffer_get_length(evb),peer().str(),
peer_channel_id_);
- int r = SendTo(socket_,peer(),evb);
+ int r = SendTo(socket_,peer(),&evb);
if (r==-1)
print_error("can't send datagram");
else
dprintf("%s #%u fsent %ib %s:%x\n",
tintstr(),id_,(int)evbuffer_get_length(evb),peer().str(),
peer_channel_id_);
- int ret = Channel::SendTo(socket_,peer(),evb); // kind of fragmentation
+ int ret = Channel::SendTo(socket_,peer(),&evb); // kind of fragmentation
if (ret > 0)
raw_bytes_up_ += ret;
evbuffer_add_32be(evb, peer_channel_id_);
static void LibeventReceiveCallback(int fd, short event, void *arg);
static void RecvDatagram (evutil_socket_t socket); // Called by LibeventReceiveCallback
static int RecvFrom(evutil_socket_t sock, Address& addr, struct evbuffer **evb); // Called by RecvDatagram
- static int SendTo(evutil_socket_t sock, const Address& addr, struct evbuffer *evb); // Called by Channel::Send()
+ static int SendTo(evutil_socket_t sock, const Address& addr, struct evbuffer **evb); // Called by Channel::Send()
static evutil_socket_t Bind(Address address, sckrwecb_t callbacks=sckrwecb_t());
static Address BoundAddress(evutil_socket_t sock);
static evutil_socket_t default_socket()
sprintf(buf+i*2,"%02x",*(data+i));
buf[i*2] = 0;
EXPECT_STREQ("74657874ababcdabcdef01000abcdefabcdeff",buf);
- ASSERT_EQ(datalen,Channel::SendTo(socket, addr, snd));
+ ASSERT_EQ(datalen,Channel::SendTo(socket, addr, &snd));
evbuffer_free(snd);
event_assign(&evrecv, evbase, socket, EV_READ, ReceiveCallback, NULL);
event_add(&evrecv, NULL);
addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK);*/
struct evbuffer *snd = evbuffer_new();
evbuffer_add_32be(snd, 1234);
- Channel::SendTo(sock1,Address("127.0.0.1:10002"),snd);
+ Channel::SendTo(sock1,Address("127.0.0.1:10002"),&snd);
evbuffer_free(snd);
event_assign(&evrecv, evbase, sock2, EV_READ, ReceiveCallback, NULL);
event_add(&evrecv, NULL);