libbgp  0.6
A C++ BGP Library.
bgp-sink.cc
Go to the documentation of this file.
1 
11 #include "bgp-sink.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <arpa/inet.h>
15 #define BGP_SINK_DEFAULT_BUFSZ 65536
16 
17 namespace libbgp {
18 
24 BgpSink::BgpSink(bool use_4b_asn) {
25  this->buffer_size = BGP_SINK_DEFAULT_BUFSZ;
26  this->buffer = (uint8_t *) malloc(buffer_size);
27  this->use_4b_asn = use_4b_asn;
28  this->logger = NULL;
29  offset_start = offset_end = 0;
30 }
31 
37  free(buffer);
38 }
39 
50 ssize_t BgpSink::fill(const uint8_t *buffer, size_t len) {
51  std::lock_guard<std::recursive_mutex> lock(mutex);
52  if (len > buffer_size) {
53  if (logger) logger->log(ERROR, "BgpSink::fill: buffer length (%d) > sink size (%d).\n", len, buffer_size);
54  return -1;
55  }
56 
57  // first try settle
58  if (offset_end + len > buffer_size) settle();
59 
60  // if still too small, expand
61  while (offset_end + len > buffer_size) {
62  expand();
63  }
64 
65  memcpy(this->buffer + offset_end, buffer, len);
66  offset_end += len;
67 
68  return len;
69 }
70 
86 ssize_t BgpSink::pour(BgpPacket **pkt) {
87  std::lock_guard<std::recursive_mutex> lock(mutex);
88 
89  uint8_t *cur = this->buffer + offset_start;
90 
91  if (offset_end - offset_start < 19) return 0;
92  if (memcmp(cur, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 16) != 0) {
93  if (logger) logger->log(ERROR, "BgpSink::pour: invalid BGP marker.\n");
94  return -2;
95  }
96 
97  uint16_t field_len = ntohs(*(uint16_t *) (cur + 16));
98 
99  if (field_len < 19 || field_len > 4096) {
100  if (logger) logger->log(ERROR, "BgpSink::pourPtr: invalid BGP packet length (%d).\n", field_len);
101  return -2;
102  }
103 
104  ssize_t bytes = getBytesInSink();
105  if (field_len > bytes) return 0; // incomplete packet, wait for more.
106 
107  offset_start += field_len;
108 
109  BgpPacket *new_pkt = new BgpPacket(logger, use_4b_asn);
110  ssize_t par_ret = new_pkt->parse(cur, field_len);
111 
112  *pkt = new_pkt;
113 
114  if (par_ret < 0) return -1;
115 
116  if (par_ret != field_len) throw "bad_packet";
117 
118  return par_ret;
119 }
120 
121 void BgpSink::settle() {
122  if (offset_start > 0) {
123  if (offset_start == offset_end) offset_start = offset_end = 0;
124  else memmove(buffer, buffer + offset_start, offset_end - offset_start);
125  }
126 }
127 
128 void BgpSink::expand() {
129  size_t new_buf_sz = buffer_size * 2;
130  size_t content_sz = getBytesInSink();
131  uint8_t *new_buffer = (uint8_t *) malloc(new_buf_sz);
132  memcpy(new_buffer, buffer + offset_start, content_sz);
133  free(buffer);
134  buffer = new_buffer;
135  buffer_size = new_buf_sz;
136  offset_start = 0;
137  offset_end = content_sz;
138  if (logger) logger->log(DEBUG, "BgpSink::expand: expanded size to %zu\n", buffer_size);
139 }
140 
146  std::lock_guard<std::recursive_mutex> lock(mutex);
147  offset_end = offset_start = 0;
148 }
149 
155 size_t BgpSink::getBytesInSink() const {
156  return offset_end - offset_start;
157 }
158 
165  this->logger = logger;
166 }
167 
168 }
ssize_t pour(BgpPacket **pkt)
Pour BGP packet out from sink.
Definition: bgp-sink.cc:86
void setLogger(BgpLogHandler *logger)
Set the logger to use. If NULL or not set, nothing will be logger.
Definition: bgp-sink.cc:164
void log(LogLevel level, const char *format_str,...)
Log a message. Consider using LIBBGP_LOG if logging the message needs a lot of computing power...
~BgpSink()
Destroy the Bgp Sink:: Bgp Sink object.
Definition: bgp-sink.cc:36
ssize_t parse(const uint8_t *from, size_t buf_sz)
Deserialize a BGP message.
Definition: bgp-packet.cc:75
void drain()
Drain the sink. (Remove all data from sink buffer)
Definition: bgp-sink.cc:145
The BGP sink.
Definition: bgp-afi.h:14
The BgpLogHandler class.
size_t getBytesInSink() const
Get amount to data in sink.
Definition: bgp-sink.cc:155
The BgpPacket class.
Definition: bgp-packet.h:26
ssize_t fill(const uint8_t *buffer, size_t len)
Fill the sink with data.
Definition: bgp-sink.cc:50
BgpSink(bool use_4b_asn)
Construct a new Bgp Sink:: Bgp Sink object.
Definition: bgp-sink.cc:24