static int da_haproxy(const struct arg *args, struct sample *smp, da_deviceinfo_t *devinfo) { struct buffer *tmp; da_propid_t prop, *pprop; da_status_t status; da_type_t proptype; const char *propname; int i; tmp = get_trash_chunk(); chunk_reset(tmp); propname = (const char *) args[0].data.str.area; i = 0; for (; propname != 0; i ++, propname = (const char *) args[i].data.str.area) { status = da_atlas_getpropid(&global_deviceatlas.atlas, propname, &prop); if (status != DA_OK) { chunk_appendf(tmp, "%c", global_deviceatlas.separator); continue; } pprop = ∝ da_atlas_getproptype(&global_deviceatlas.atlas, *pprop, &proptype); switch (proptype) { case DA_TYPE_BOOLEAN: { bool val; status = da_getpropboolean(devinfo, *pprop, &val); if (status == DA_OK) { chunk_appendf(tmp, "%d", val); } break; } case DA_TYPE_INTEGER: case DA_TYPE_NUMBER: { long val; status = da_getpropinteger(devinfo, *pprop, &val); if (status == DA_OK) { chunk_appendf(tmp, "%ld", val); } break; } case DA_TYPE_STRING: { const char *val; status = da_getpropstring(devinfo, *pprop, &val); if (status == DA_OK) { chunk_appendf(tmp, "%s", val); } break; } default: break; } chunk_appendf(tmp, "%c", global_deviceatlas.separator); } da_close(devinfo); if (tmp->data) { --tmp->data; tmp->area[tmp->data] = 0; } smp->data.u.str.area = tmp->area; smp->data.u.str.data = tmp->data; return 1; }
int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connection *remote) { const char pp2_signature[] = PP2_SIGNATURE; int ret = 0; struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf; struct sockaddr_storage null_addr = {0}; struct sockaddr_storage *src = &null_addr; struct sockaddr_storage *dst = &null_addr; #ifdef USE_OPENSSL int tlv_len = 0; char *value = NULL; struct tlv_ssl *tlv; int ssl_tlv_len = 0; struct chunk *cn_trash; #endif if (buf_len < PP2_HEADER_LEN) return 0; memcpy(hdr->sig, pp2_signature, PP2_SIGNATURE_LEN); if (remote) { src = &remote->addr.from; dst = &remote->addr.to; } if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET) { if (buf_len < PP2_HDR_LEN_INET) return 0; hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY; hdr->fam = PP2_FAM_INET | PP2_TRANS_STREAM; hdr->addr.ip4.src_addr = ((struct sockaddr_in *)src)->sin_addr.s_addr; hdr->addr.ip4.dst_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr; hdr->addr.ip4.src_port = ((struct sockaddr_in *)src)->sin_port; hdr->addr.ip4.dst_port = ((struct sockaddr_in *)dst)->sin_port; ret = PP2_HDR_LEN_INET; } else if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET6) { if (buf_len < PP2_HDR_LEN_INET6) return 0; hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY; hdr->fam = PP2_FAM_INET6 | PP2_TRANS_STREAM; memcpy(hdr->addr.ip6.src_addr, &((struct sockaddr_in6 *)src)->sin6_addr, 16); memcpy(hdr->addr.ip6.dst_addr, &((struct sockaddr_in6 *)dst)->sin6_addr, 16); hdr->addr.ip6.src_port = ((struct sockaddr_in6 *)src)->sin6_port; hdr->addr.ip6.dst_port = ((struct sockaddr_in6 *)dst)->sin6_port; ret = PP2_HDR_LEN_INET6; } else { if (buf_len < PP2_HDR_LEN_UNSPEC) return 0; hdr->ver_cmd = PP2_VERSION | PP2_CMD_LOCAL; hdr->fam = PP2_FAM_UNSPEC | PP2_TRANS_UNSPEC; ret = PP2_HDR_LEN_UNSPEC; } #ifdef USE_OPENSSL if (srv->pp_opts & SRV_PP_V2_SSL) { if ((buf_len - ret) < sizeof(struct tlv_ssl)) return 0; tlv = (struct tlv_ssl *)&buf[ret]; memset(tlv, 0, sizeof(struct tlv_ssl)); ssl_tlv_len += sizeof(struct tlv_ssl); tlv->tlv.type = PP2_TYPE_SSL; if (ssl_sock_is_ssl(remote)) { tlv->client |= PP2_CLIENT_SSL; value = ssl_sock_get_version(remote); if (value) { tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len-ret-ssl_tlv_len), PP2_TYPE_SSL_VERSION, strlen(value), value); ssl_tlv_len += tlv_len; } if (ssl_sock_get_cert_used_sess(remote)) { tlv->client |= PP2_CLIENT_CERT_SESS; tlv->verify = htonl(ssl_sock_get_verify_result(remote)); if (ssl_sock_get_cert_used_conn(remote)) tlv->client |= PP2_CLIENT_CERT_CONN; } if (srv->pp_opts & SRV_PP_V2_SSL_CN) { cn_trash = get_trash_chunk(); if (ssl_sock_get_remote_common_name(remote, cn_trash) > 0) { tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, cn_trash->len, cn_trash->str); ssl_tlv_len += tlv_len; } } } tlv->tlv.length_hi = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) >> 8; tlv->tlv.length_lo = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) & 0x00ff; ret += ssl_tlv_len; } #endif hdr->len = htons((uint16_t)(ret - PP2_HEADER_LEN)); return ret; }