14 #include <arpa/inet.h> 15 #define BGP_SINK_DEFAULT_BUFSZ 65536 25 this->buffer_size = BGP_SINK_DEFAULT_BUFSZ;
26 this->buffer = (uint8_t *) malloc(buffer_size);
27 this->use_4b_asn = use_4b_asn;
29 offset_start = offset_end = 0;
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);
58 if (offset_end + len > buffer_size) settle();
61 while (offset_end + len > buffer_size) {
65 memcpy(this->buffer + offset_end, buffer, len);
87 std::lock_guard<std::recursive_mutex> lock(mutex);
89 uint8_t *cur = this->buffer + offset_start;
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");
97 uint16_t field_len = ntohs(*(uint16_t *) (cur + 16));
99 if (field_len < 19 || field_len > 4096) {
100 if (logger) logger->
log(ERROR,
"BgpSink::pourPtr: invalid BGP packet length (%d).\n", field_len);
105 if (field_len > bytes)
return 0;
107 offset_start += field_len;
110 ssize_t par_ret = new_pkt->
parse(cur, field_len);
114 if (par_ret < 0)
return -1;
116 if (par_ret != field_len)
throw "bad_packet";
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);
128 void BgpSink::expand() {
129 size_t new_buf_sz = buffer_size * 2;
131 uint8_t *new_buffer = (uint8_t *) malloc(new_buf_sz);
132 memcpy(new_buffer, buffer + offset_start, content_sz);
135 buffer_size = new_buf_sz;
137 offset_end = content_sz;
138 if (logger) logger->
log(DEBUG,
"BgpSink::expand: expanded size to %zu\n", buffer_size);
146 std::lock_guard<std::recursive_mutex> lock(mutex);
147 offset_end = offset_start = 0;
156 return offset_end - offset_start;
165 this->logger = logger;
ssize_t pour(BgpPacket **pkt)
Pour BGP packet out from sink.
void setLogger(BgpLogHandler *logger)
Set the logger to use. If NULL or not set, nothing will be logger.
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.
ssize_t parse(const uint8_t *from, size_t buf_sz)
Deserialize a BGP message.
void drain()
Drain the sink. (Remove all data from sink buffer)
size_t getBytesInSink() const
Get amount to data in sink.
ssize_t fill(const uint8_t *buffer, size_t len)
Fill the sink with data.
BgpSink(bool use_4b_asn)
Construct a new Bgp Sink:: Bgp Sink object.