Skip to content

Commit 01aa21b

Browse files
mohitkhullarakshatsikarwar
authored andcommitted
handle pmuv
Signed-off-by: mohitkhullar <[email protected]>
1 parent d762c07 commit 01aa21b

File tree

1 file changed

+115
-11
lines changed

1 file changed

+115
-11
lines changed

net/net_evbuffer.c

Lines changed: 115 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ static void host_connected_info_free(struct host_connected_info *info)
814814
struct accept_info {
815815
int fd;
816816
int secure; /* whether connection is routed from a secure pmux port */
817+
int pmuv;
817818
int badrte;
818819
struct evbuffer *buf;
819820
int to_len;
@@ -840,7 +841,7 @@ static void do_read(int, short, void *);
840841
static void accept_info_free(struct accept_info *);
841842

842843
static void accept_info_new(netinfo_type *netinfo_ptr, struct sockaddr_in *addr, int fd, int secure,
843-
int badrte)
844+
int badrte, int pmuv)
844845
{
845846
check_base_thd();
846847
++pending_connections;
@@ -856,6 +857,7 @@ static void accept_info_new(netinfo_type *netinfo_ptr, struct sockaddr_in *addr,
856857
a->fd = fd;
857858
a->secure = secure;
858859
a->badrte = badrte;
860+
a->pmuv = pmuv;
859861
a->ev = event_new(base, fd, EV_READ, do_read, a);
860862
event_add(a->ev, NULL);
861863
}
@@ -2928,6 +2930,75 @@ static int should_reject_request(uint8_t first_byte)
29282930
return check_appsock_limit(pending_connections, is_admin);
29292931
}
29302932

2933+
/* PMUV REQUEST/RESPONSE */
2934+
enum request { V_WHO = 1, V_NAK = 2, V_ACK = 3 };
2935+
enum response { V_NONE = 0, V_ID = 1 };
2936+
2937+
static int portmux_server_side_validation(struct accept_info *a, char request) {
2938+
ssize_t rc;
2939+
char response;
2940+
switch(request) {
2941+
case V_WHO:
2942+
response = V_ID;
2943+
rc = write(a->fd, &response, 1);
2944+
if (rc != 1) {
2945+
logmsg(LOGMSG_ERROR, "%s:write failure fd:%d rc:%zd (%s)\n", __func__,
2946+
a->fd, rc, strerror(errno));
2947+
return 1;
2948+
}
2949+
2950+
uint32_t size = 0;
2951+
uint32_t features = htonl(0);
2952+
/* format the triplet into a string.
2953+
* snprintf returns the number of characters printed, excluding
2954+
* the null byte used to end output to strings - we want that too.
2955+
*/
2956+
char buf[512];
2957+
netinfo_type *netinfo_ptr = a->netinfo_ptr;
2958+
uint32_t buflen = snprintf(buf, sizeof(buf), "%s/%s/%s", netinfo_ptr->app,
2959+
netinfo_ptr->service, netinfo_ptr->instance) +
2960+
1;
2961+
if (buflen > sizeof(buf)) {
2962+
return 1;
2963+
}
2964+
evbuffer_drain(a->buf, 1);
2965+
/* Logic from portmuxuser.c portmux_server_side_validation */
2966+
size_t total_len = 0;
2967+
struct evbuffer_iovec iov[3];
2968+
iov[0].iov_base = (void *)&size;
2969+
iov[0].iov_len = sizeof(uint32_t);
2970+
iov[1].iov_base = (void *)&features;
2971+
iov[1].iov_len = sizeof(uint32_t);
2972+
iov[2].iov_base = (void *)buf;
2973+
iov[2].iov_len = buflen;
2974+
size = iov[1].iov_len + iov[2].iov_len;
2975+
total_len = size + iov[0].iov_len;
2976+
size = htonl(size);
2977+
evbuffer_add_iovec(a->buf, iov, 3);
2978+
rc = evbuffer_write(a->buf, a->fd);
2979+
if (rc != total_len) {
2980+
logmsg(LOGMSG_ERROR, "%s:unable to write fd:%d rc:%zd (%s)\n", __func__,
2981+
a->fd, rc, strerror(errno));
2982+
return 1;
2983+
}
2984+
/* Still in pmuv validation mode, don't reset the flag */
2985+
a->ev = event_new(base, a->fd, EV_READ, do_read, a);
2986+
event_add(a->ev, NULL);
2987+
return 0;
2988+
case V_NAK:
2989+
/* Validation failed */
2990+
return 1;
2991+
case V_ACK:
2992+
/* Validation done */
2993+
a->pmuv = 0;
2994+
a->ev = event_new(base, a->fd, EV_READ, do_read, a);
2995+
event_add(a->ev, NULL);
2996+
return 0;
2997+
default:
2998+
return 1;
2999+
}
3000+
}
3001+
29313002
static void do_read(int fd, short what, void *data)
29323003
{
29333004
check_base_thd();
@@ -2941,6 +3012,18 @@ static void do_read(int fd, short what, void *data)
29413012
}
29423013
uint8_t first_byte;
29433014
evbuffer_copyout(buf, &first_byte, 1);
3015+
if (a->pmuv) {
3016+
a->buf = buf;
3017+
evbuffer_drain(buf, 1);
3018+
if (portmux_server_side_validation(a, first_byte) != 0) {
3019+
evbuffer_free(buf);
3020+
shutdown_close(fd);
3021+
} else {
3022+
evbuffer_free(buf);
3023+
a->buf = NULL;
3024+
}
3025+
return;
3026+
}
29443027
if (first_byte == 0) { /* replication or offloadsql */
29453028
evbuffer_drain(buf, 1);
29463029
a->buf = buf;
@@ -2967,7 +3050,7 @@ static void do_read(int fd, short what, void *data)
29673050
if (badrte) {
29683051
// Failed to handle fd because of badrte
29693052
rem_appsock_connection_evbuffer();
2970-
accept_info_new(netinfo_ptr, &ss, fd, secure, 1);
3053+
accept_info_new(netinfo_ptr, &ss, fd, secure, 1, 0);
29713054
return;
29723055
}
29733056
if (handle_appsock(netinfo_ptr, &ss, first_byte, buf, fd) != 0) {
@@ -2977,14 +3060,24 @@ static void do_read(int fd, short what, void *data)
29773060
}
29783061
}
29793062

3063+
static void accept_pmuv(struct evconnlistener *listener, evutil_socket_t fd,
3064+
struct sockaddr *addr, int len, void *data)
3065+
{
3066+
check_base_thd();
3067+
struct net_info *n = data;
3068+
netinfo_type *netinfo_ptr = n->netinfo_ptr;
3069+
netinfo_ptr->num_accepts++;
3070+
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 0, 0, 1);
3071+
}
3072+
29803073
static void accept_cb(struct evconnlistener *listener, evutil_socket_t fd,
29813074
struct sockaddr *addr, int len, void *data)
29823075
{
29833076
check_base_thd();
29843077
struct net_info *n = data;
29853078
netinfo_type *netinfo_ptr = n->netinfo_ptr;
29863079
netinfo_ptr->num_accepts++;
2987-
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 0, 0);
3080+
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 0, 0, 0);
29883081
}
29893082

29903083
static void accept_secure(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len,
@@ -2994,7 +3087,7 @@ static void accept_secure(struct evconnlistener *listener, evutil_socket_t fd, s
29943087
struct net_info *n = data;
29953088
netinfo_type *netinfo_ptr = n->netinfo_ptr;
29963089
netinfo_ptr->num_accepts++;
2997-
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 1, 0);
3090+
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 1, 0, 0);
29983091
}
29993092

30003093
static void accept_error_cb(struct evconnlistener *listener, void *data)
@@ -3027,7 +3120,7 @@ static void reopen_unix(int fd, struct net_info *n)
30273120
(m)->cmsg_level == SOL_SOCKET && (m)->cmsg_type == SCM_RIGHTS)
30283121
#endif
30293122

3030-
static int recvfd(int pmux_fd, int *secure)
3123+
static int recvfd(int pmux_fd, int *secure, int *pmuv)
30313124
{
30323125
int newfd = -1;
30333126
char buf[sizeof("pmux") - 1];
@@ -3081,13 +3174,15 @@ static int recvfd(int pmux_fd, int *secure)
30813174
}
30823175
newfd = *(int *)CMSG_DATA(m);
30833176
# endif
3084-
if (memcmp(buf, "pmux", sizeof(buf)) != 0 && memcmp(buf, "spmu", sizeof(buf)) != 0) {
3177+
if (memcmp(buf, "pmux", sizeof(buf)) != 0 && memcmp(buf, "spmu", sizeof(buf)) != 0 &&
3178+
memcmp(buf, "pmuv", sizeof(buf))) {
30853179
shutdown_close(newfd);
30863180
logmsg(LOGMSG_ERROR, "%s:recvmsg pmux_fd:%d unexpected msg:%.*s\n", __func__,
30873181
pmux_fd, (int)sizeof(buf), buf);
30883182
return -1;
30893183
}
30903184
*secure = (memcmp(buf, "spmu", sizeof(buf)) == 0);
3185+
*pmuv = (memcmp(buf, "pmuv", sizeof(buf)) == 0);
30913186
return newfd;
30923187
}
30933188

@@ -3096,14 +3191,21 @@ static void do_recvfd(int pmux_fd, short what, void *data)
30963191
check_base_thd();
30973192
struct net_info *n = data;
30983193
int secure;
3099-
int newfd = recvfd(pmux_fd, &secure);
3194+
int pmuv;
3195+
int newfd = recvfd(pmux_fd, &secure, &pmuv);
31003196
if (newfd == 0) return;
31013197
if (newfd < 0) {
31023198
reopen_unix(pmux_fd, n);
31033199
return;
31043200
}
31053201
make_server_socket(newfd);
3106-
ssize_t rc = write(newfd, "0\n", 2);
3202+
ssize_t rc;
3203+
if (pmuv) {
3204+
/* Validate */
3205+
rc = write(newfd, "1\n", 2);
3206+
} else {
3207+
rc = write(newfd, "0\n", 2);
3208+
}
31073209
if (rc != 2) {
31083210
logmsg(LOGMSG_ERROR, "%s:write pmux_fd:%d rc:%zd (%s)\n", __func__, pmux_fd, rc, strerror(errno));
31093211
shutdown_close(newfd);
@@ -3113,10 +3215,12 @@ static void do_recvfd(int pmux_fd, short what, void *data)
31133215
struct sockaddr *addr = (struct sockaddr *)&saddr;
31143216
socklen_t addrlen = sizeof(saddr);
31153217
getpeername(newfd, addr, &addrlen);
3116-
if (!secure)
3117-
accept_cb(NULL, newfd, addr, addrlen, n);
3118-
else
3218+
if (secure)
31193219
accept_secure(NULL, newfd, addr, addrlen, n);
3220+
else if (pmuv)
3221+
accept_pmuv(NULL, newfd, addr, addrlen, n);
3222+
else
3223+
accept_cb(NULL, newfd, addr, addrlen, n);
31203224
}
31213225

31223226
static int process_reg_reply(char *res, struct net_info *n, int unix_fd)

0 commit comments

Comments
 (0)