Ejemplo n.º 1
0
bool lsb_find_heka_message(lsb_heka_message *m,
                           lsb_input_buffer *ib,
                           bool decode,
                           size_t *discarded_bytes,
                           lsb_logger *logger)
{
  if (!m || !ib || !discarded_bytes) {
    if (logger && logger->cb) {
      logger->cb(logger->context, __func__, 4, LSB_ERR_UTIL_NULL);
    }
    return false;
  }

  *discarded_bytes = 0;
  if (ib->readpos == ib->scanpos) {
    return false; // empty buffer
  }

  char *p = memchr(&ib->buf[ib->scanpos], 0x1e, ib->readpos - ib->scanpos);
  if (p) {
    if (p != ib->buf + ib->scanpos) {
      // partial buffer skipped before locating a possible header
      *discarded_bytes += p - ib->buf - ib->scanpos;
    }
    ib->scanpos = p - ib->buf;

    if (ib->readpos - ib->scanpos < 2) {
      return false; // header length is not buf
    }

    size_t hlen = (unsigned char)ib->buf[ib->scanpos + 1];
    size_t hend = ib->scanpos + hlen + 3;
    if (hend > ib->readpos) {
      return false; // header is not in buf
    }
    if (ib->buf[hend - 1] != 0x1f) {
      // invalid header length
      ++ib->scanpos;
      ++*discarded_bytes;
      size_t db;
      bool b =  lsb_find_heka_message(m, ib, decode, &db, logger);
      *discarded_bytes += db;
      return b;
    }

    if (!ib->msglen) {
      ib->msglen = decode_header(&ib->buf[ib->scanpos + 2], hlen,
                                 ib->maxsize - LSB_MAX_HDR_SIZE);
    }

    if (ib->msglen) {
      size_t mend = hend + ib->msglen;
      if (mend > ib->readpos) {
        return false; // message is not in buf
      }

      if (decode) {
        if (lsb_decode_heka_message(m, &ib->buf[hend], ib->msglen, logger)) {
          ib->scanpos = mend;
          ib->msglen = 0;
          return true;
        } else {
          // message decode failure
          ++ib->scanpos;
          ++*discarded_bytes;
          ib->msglen = 0;
          size_t db;
          bool b =  lsb_find_heka_message(m, ib, decode, &db, logger);
          *discarded_bytes += db;
          return b;
        }
      } else {
        // allow a framed message is non Heka protobuf format
        lsb_clear_heka_message(m);
        m->raw.s = &ib->buf[hend];
        m->raw.len = ib->msglen;
        ib->scanpos = mend;
        ib->msglen = 0;
        return true;
      }
    } else {
      // header decode failure
      ++ib->scanpos;
      ++*discarded_bytes;
      size_t db;
      bool b =  lsb_find_heka_message(m, ib, decode, &db, logger);
      *discarded_bytes += db;
      return b;
    }
  } else {
    // full buffer skipped since no header was located
    *discarded_bytes += ib->readpos - ib->scanpos;
    ib->scanpos = ib->readpos = 0;
  }
  return false;
}
Ejemplo n.º 2
0
static int inject_message_input(lua_State *lua)
{
  lsb_lua_sandbox *lsb = lua_touserdata(lua, lua_upvalueindex(1));
  if (NULL == lsb) {
    return luaL_error(lua, "%s() invalid lightuserdata", im_func_name);
  }

  const char *scp =  NULL;
  double ncp = NAN;
  int t = lua_type(lua, 2);
  switch (t) {
  case LUA_TNUMBER:
    ncp = lua_tonumber(lua, 2);
    break;
  case LUA_TSTRING:
    scp = lua_tostring(lua, 2);
    break;
  case LUA_TNONE:
  case LUA_TNIL:
    break;
  default:
    return luaL_error(lua, "%s() unsupported checkpoint type: %s", im_func_name,
                      lua_typename(lua, t));
  }

  lsb_const_string output;
  t = lua_type(lua, 1);
  switch (t) {
  case LUA_TUSERDATA:
    {
      heka_stream_reader *hsr = luaL_checkudata(lua, 1,
                                                mozsvc_heka_stream_reader);
      if (hsr->msg.raw.s) {
        output.len = hsr->msg.raw.len;
        output.s = hsr->msg.raw.s;
      } else {
        return luaL_error(lua, "%s() attempted to inject a nil message",
                          im_func_name);
      }
    }
    break;
  case LUA_TSTRING:
    {
      lsb_heka_message m;
      lsb_init_heka_message(&m, 8);
      output.s = lua_tolstring(lua, 1, &output.len);
      bool ok = lsb_decode_heka_message(&m, output.s, output.len, NULL);
      lsb_free_heka_message(&m);
      if (!ok) {
        return luaL_error(lua, "%s() attempted to inject a invalid protobuf "
                          "string", im_func_name);
      }
    }
    break;
  case LUA_TTABLE:
    if (heka_encode_message_table(lsb, 1)) {
      const char *err = lsb_get_error(lsb);
      if (strlen(err) == 0) err = "exceeded output_limit";
      return luaL_error(lua, "%s() failed: %s", im_func_name, err);
    }
    output.len = 0;
    output.s = lsb_get_output(lsb, &output.len);
    break;
  default:
    return luaL_error(lua, "%s() unsupported message type: %s",
                      im_func_name, lua_typename(lua, t));
  }

  lsb_heka_sandbox *hsb = lsb_get_parent(lsb);
  if (hsb->cb.iim(hsb->parent, output.s, output.len, ncp, scp) != 0) {
    return luaL_error(lua, "%s() failed: rejected by the callback",
                      im_func_name);
  }
  ++hsb->stats.im_cnt;
  hsb->stats.im_bytes += output.len;
  return 0;
}