summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c203
1 files changed, 117 insertions, 86 deletions
diff --git a/mux.c b/mux.c
index 784e942ba..5278ce4b6 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.45 2014/04/28 03:09:18 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.46 2014/07/15 15:54:14 millert Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -509,29 +509,33 @@ process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
509} 509}
510 510
511static char * 511static char *
512format_forward(u_int ftype, Forward *fwd) 512format_forward(u_int ftype, struct Forward *fwd)
513{ 513{
514 char *ret; 514 char *ret;
515 515
516 switch (ftype) { 516 switch (ftype) {
517 case MUX_FWD_LOCAL: 517 case MUX_FWD_LOCAL:
518 xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", 518 xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
519 (fwd->listen_path != NULL) ? fwd->listen_path :
519 (fwd->listen_host == NULL) ? 520 (fwd->listen_host == NULL) ?
520 (options.gateway_ports ? "*" : "LOCALHOST") : 521 (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
521 fwd->listen_host, fwd->listen_port, 522 fwd->listen_host, fwd->listen_port,
523 (fwd->connect_path != NULL) ? fwd->connect_path :
522 fwd->connect_host, fwd->connect_port); 524 fwd->connect_host, fwd->connect_port);
523 break; 525 break;
524 case MUX_FWD_DYNAMIC: 526 case MUX_FWD_DYNAMIC:
525 xasprintf(&ret, "dynamic forward %.200s:%d -> *", 527 xasprintf(&ret, "dynamic forward %.200s:%d -> *",
526 (fwd->listen_host == NULL) ? 528 (fwd->listen_host == NULL) ?
527 (options.gateway_ports ? "*" : "LOCALHOST") : 529 (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
528 fwd->listen_host, fwd->listen_port); 530 fwd->listen_host, fwd->listen_port);
529 break; 531 break;
530 case MUX_FWD_REMOTE: 532 case MUX_FWD_REMOTE:
531 xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", 533 xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
534 (fwd->listen_path != NULL) ? fwd->listen_path :
532 (fwd->listen_host == NULL) ? 535 (fwd->listen_host == NULL) ?
533 "LOCALHOST" : fwd->listen_host, 536 "LOCALHOST" : fwd->listen_host,
534 fwd->listen_port, 537 fwd->listen_port,
538 (fwd->connect_path != NULL) ? fwd->connect_path :
535 fwd->connect_host, fwd->connect_port); 539 fwd->connect_host, fwd->connect_port);
536 break; 540 break;
537 default: 541 default:
@@ -551,14 +555,18 @@ compare_host(const char *a, const char *b)
551} 555}
552 556
553static int 557static int
554compare_forward(Forward *a, Forward *b) 558compare_forward(struct Forward *a, struct Forward *b)
555{ 559{
556 if (!compare_host(a->listen_host, b->listen_host)) 560 if (!compare_host(a->listen_host, b->listen_host))
557 return 0; 561 return 0;
562 if (!compare_host(a->listen_path, b->listen_path))
563 return 0;
558 if (a->listen_port != b->listen_port) 564 if (a->listen_port != b->listen_port)
559 return 0; 565 return 0;
560 if (!compare_host(a->connect_host, b->connect_host)) 566 if (!compare_host(a->connect_host, b->connect_host))
561 return 0; 567 return 0;
568 if (!compare_host(a->connect_path, b->connect_path))
569 return 0;
562 if (a->connect_port != b->connect_port) 570 if (a->connect_port != b->connect_port)
563 return 0; 571 return 0;
564 572
@@ -570,7 +578,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
570{ 578{
571 struct mux_channel_confirm_ctx *fctx = ctxt; 579 struct mux_channel_confirm_ctx *fctx = ctxt;
572 char *failmsg = NULL; 580 char *failmsg = NULL;
573 Forward *rfwd; 581 struct Forward *rfwd;
574 Channel *c; 582 Channel *c;
575 Buffer out; 583 Buffer out;
576 584
@@ -587,7 +595,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
587 rfwd = &options.remote_forwards[fctx->fid]; 595 rfwd = &options.remote_forwards[fctx->fid];
588 debug("%s: %s for: listen %d, connect %s:%d", __func__, 596 debug("%s: %s for: listen %d, connect %s:%d", __func__,
589 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 597 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
590 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 598 rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
599 rfwd->connect_host, rfwd->connect_port);
591 if (type == SSH2_MSG_REQUEST_SUCCESS) { 600 if (type == SSH2_MSG_REQUEST_SUCCESS) {
592 if (rfwd->listen_port == 0) { 601 if (rfwd->listen_port == 0) {
593 rfwd->allocated_port = packet_get_int(); 602 rfwd->allocated_port = packet_get_int();
@@ -607,8 +616,12 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
607 } else { 616 } else {
608 if (rfwd->listen_port == 0) 617 if (rfwd->listen_port == 0)
609 channel_update_permitted_opens(rfwd->handle, -1); 618 channel_update_permitted_opens(rfwd->handle, -1);
610 xasprintf(&failmsg, "remote port forwarding failed for " 619 if (rfwd->listen_path != NULL)
611 "listen port %d", rfwd->listen_port); 620 xasprintf(&failmsg, "remote port forwarding failed for "
621 "listen path %s", rfwd->listen_path);
622 else
623 xasprintf(&failmsg, "remote port forwarding failed for "
624 "listen port %d", rfwd->listen_port);
612 } 625 }
613 fail: 626 fail:
614 error("%s: %s", __func__, failmsg); 627 error("%s: %s", __func__, failmsg);
@@ -627,34 +640,46 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
627static int 640static int
628process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 641process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
629{ 642{
630 Forward fwd; 643 struct Forward fwd;
631 char *fwd_desc = NULL; 644 char *fwd_desc = NULL;
645 char *listen_addr, *connect_addr;
632 u_int ftype; 646 u_int ftype;
633 u_int lport, cport; 647 u_int lport, cport;
634 int i, ret = 0, freefwd = 1; 648 int i, ret = 0, freefwd = 1;
635 649
636 fwd.listen_host = fwd.connect_host = NULL; 650 /* XXX - lport/cport check redundant */
637 if (buffer_get_int_ret(&ftype, m) != 0 || 651 if (buffer_get_int_ret(&ftype, m) != 0 ||
638 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 652 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
639 buffer_get_int_ret(&lport, m) != 0 || 653 buffer_get_int_ret(&lport, m) != 0 ||
640 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 654 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
641 buffer_get_int_ret(&cport, m) != 0 || 655 buffer_get_int_ret(&cport, m) != 0 ||
642 lport > 65535 || cport > 65535) { 656 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
657 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
643 error("%s: malformed message", __func__); 658 error("%s: malformed message", __func__);
644 ret = -1; 659 ret = -1;
645 goto out; 660 goto out;
646 } 661 }
647 fwd.listen_port = lport; 662 if (*listen_addr == '\0') {
648 fwd.connect_port = cport; 663 free(listen_addr);
649 if (*fwd.listen_host == '\0') { 664 listen_addr = NULL;
650 free(fwd.listen_host);
651 fwd.listen_host = NULL;
652 } 665 }
653 if (*fwd.connect_host == '\0') { 666 if (*connect_addr == '\0') {
654 free(fwd.connect_host); 667 free(connect_addr);
655 fwd.connect_host = NULL; 668 connect_addr = NULL;
656 } 669 }
657 670
671 memset(&fwd, 0, sizeof(fwd));
672 fwd.listen_port = lport;
673 if (fwd.listen_port == PORT_STREAMLOCAL)
674 fwd.listen_path = listen_addr;
675 else
676 fwd.listen_host = listen_addr;
677 fwd.connect_port = cport;
678 if (fwd.connect_port == PORT_STREAMLOCAL)
679 fwd.connect_path = connect_addr;
680 else
681 fwd.connect_host = connect_addr;
682
658 debug2("%s: channel %d: request %s", __func__, c->self, 683 debug2("%s: channel %d: request %s", __func__, c->self,
659 (fwd_desc = format_forward(ftype, &fwd))); 684 (fwd_desc = format_forward(ftype, &fwd)));
660 685
@@ -662,25 +687,30 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
662 ftype != MUX_FWD_DYNAMIC) { 687 ftype != MUX_FWD_DYNAMIC) {
663 logit("%s: invalid forwarding type %u", __func__, ftype); 688 logit("%s: invalid forwarding type %u", __func__, ftype);
664 invalid: 689 invalid:
665 free(fwd.listen_host); 690 free(listen_addr);
666 free(fwd.connect_host); 691 free(connect_addr);
667 buffer_put_int(r, MUX_S_FAILURE); 692 buffer_put_int(r, MUX_S_FAILURE);
668 buffer_put_int(r, rid); 693 buffer_put_int(r, rid);
669 buffer_put_cstring(r, "Invalid forwarding request"); 694 buffer_put_cstring(r, "Invalid forwarding request");
670 return 0; 695 return 0;
671 } 696 }
672 if (fwd.listen_port >= 65536) { 697 if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
698 logit("%s: streamlocal and dynamic forwards "
699 "are mutually exclusive", __func__);
700 goto invalid;
701 }
702 if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
673 logit("%s: invalid listen port %u", __func__, 703 logit("%s: invalid listen port %u", __func__,
674 fwd.listen_port); 704 fwd.listen_port);
675 goto invalid; 705 goto invalid;
676 } 706 }
677 if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC && 707 if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536)
678 ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { 708 || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
679 logit("%s: invalid connect port %u", __func__, 709 logit("%s: invalid connect port %u", __func__,
680 fwd.connect_port); 710 fwd.connect_port);
681 goto invalid; 711 goto invalid;
682 } 712 }
683 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) { 713 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) {
684 logit("%s: missing connect host", __func__); 714 logit("%s: missing connect host", __func__);
685 goto invalid; 715 goto invalid;
686 } 716 }
@@ -731,9 +761,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
731 } 761 }
732 762
733 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { 763 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
734 if (!channel_setup_local_fwd_listener(fwd.listen_host, 764 if (!channel_setup_local_fwd_listener(&fwd,
735 fwd.listen_port, fwd.connect_host, fwd.connect_port, 765 &options.fwd_opts)) {
736 options.gateway_ports)) {
737 fail: 766 fail:
738 logit("slave-requested %s failed", fwd_desc); 767 logit("slave-requested %s failed", fwd_desc);
739 buffer_put_int(r, MUX_S_FAILURE); 768 buffer_put_int(r, MUX_S_FAILURE);
@@ -746,8 +775,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
746 } else { 775 } else {
747 struct mux_channel_confirm_ctx *fctx; 776 struct mux_channel_confirm_ctx *fctx;
748 777
749 fwd.handle = channel_request_remote_forwarding(fwd.listen_host, 778 fwd.handle = channel_request_remote_forwarding(&fwd);
750 fwd.listen_port, fwd.connect_host, fwd.connect_port);
751 if (fwd.handle < 0) 779 if (fwd.handle < 0)
752 goto fail; 780 goto fail;
753 add_remote_forward(&options, &fwd); 781 add_remote_forward(&options, &fwd);
@@ -768,7 +796,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
768 free(fwd_desc); 796 free(fwd_desc);
769 if (freefwd) { 797 if (freefwd) {
770 free(fwd.listen_host); 798 free(fwd.listen_host);
799 free(fwd.listen_path);
771 free(fwd.connect_host); 800 free(fwd.connect_host);
801 free(fwd.connect_path);
772 } 802 }
773 return ret; 803 return ret;
774} 804}
@@ -776,36 +806,47 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
776static int 806static int
777process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 807process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
778{ 808{
779 Forward fwd, *found_fwd; 809 struct Forward fwd, *found_fwd;
780 char *fwd_desc = NULL; 810 char *fwd_desc = NULL;
781 const char *error_reason = NULL; 811 const char *error_reason = NULL;
812 char *listen_addr = NULL, *connect_addr = NULL;
782 u_int ftype; 813 u_int ftype;
783 int i, listen_port, ret = 0; 814 int i, ret = 0;
784 u_int lport, cport; 815 u_int lport, cport;
785 816
786 fwd.listen_host = fwd.connect_host = NULL;
787 if (buffer_get_int_ret(&ftype, m) != 0 || 817 if (buffer_get_int_ret(&ftype, m) != 0 ||
788 (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || 818 (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||
789 buffer_get_int_ret(&lport, m) != 0 || 819 buffer_get_int_ret(&lport, m) != 0 ||
790 (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || 820 (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||
791 buffer_get_int_ret(&cport, m) != 0 || 821 buffer_get_int_ret(&cport, m) != 0 ||
792 lport > 65535 || cport > 65535) { 822 (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
823 (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
793 error("%s: malformed message", __func__); 824 error("%s: malformed message", __func__);
794 ret = -1; 825 ret = -1;
795 goto out; 826 goto out;
796 } 827 }
797 fwd.listen_port = lport;
798 fwd.connect_port = cport;
799 828
800 if (*fwd.listen_host == '\0') { 829 if (*listen_addr == '\0') {
801 free(fwd.listen_host); 830 free(listen_addr);
802 fwd.listen_host = NULL; 831 listen_addr = NULL;
803 } 832 }
804 if (*fwd.connect_host == '\0') { 833 if (*connect_addr == '\0') {
805 free(fwd.connect_host); 834 free(connect_addr);
806 fwd.connect_host = NULL; 835 connect_addr = NULL;
807 } 836 }
808 837
838 memset(&fwd, 0, sizeof(fwd));
839 fwd.listen_port = lport;
840 if (fwd.listen_port == PORT_STREAMLOCAL)
841 fwd.listen_path = listen_addr;
842 else
843 fwd.listen_host = listen_addr;
844 fwd.connect_port = cport;
845 if (fwd.connect_port == PORT_STREAMLOCAL)
846 fwd.connect_path = connect_addr;
847 else
848 fwd.connect_host = connect_addr;
849
809 debug2("%s: channel %d: request cancel %s", __func__, c->self, 850 debug2("%s: channel %d: request cancel %s", __func__, c->self,
810 (fwd_desc = format_forward(ftype, &fwd))); 851 (fwd_desc = format_forward(ftype, &fwd)));
811 852
@@ -840,18 +881,14 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
840 * This shouldn't fail unless we confused the host/port 881 * This shouldn't fail unless we confused the host/port
841 * between options.remote_forwards and permitted_opens. 882 * between options.remote_forwards and permitted_opens.
842 * However, for dynamic allocated listen ports we need 883 * However, for dynamic allocated listen ports we need
843 * to lookup the actual listen port. 884 * to use the actual listen port.
844 */ 885 */
845 listen_port = (fwd.listen_port == 0) ? 886 if (channel_request_rforward_cancel(found_fwd) == -1)
846 found_fwd->allocated_port : fwd.listen_port;
847 if (channel_request_rforward_cancel(fwd.listen_host,
848 listen_port) == -1)
849 error_reason = "port not in permitted opens"; 887 error_reason = "port not in permitted opens";
850 } else { /* local and dynamic forwards */ 888 } else { /* local and dynamic forwards */
851 /* Ditto */ 889 /* Ditto */
852 if (channel_cancel_lport_listener(fwd.listen_host, 890 if (channel_cancel_lport_listener(&fwd, fwd.connect_port,
853 fwd.listen_port, fwd.connect_port, 891 &options.fwd_opts) == -1)
854 options.gateway_ports) == -1)
855 error_reason = "port not found"; 892 error_reason = "port not found";
856 } 893 }
857 894
@@ -860,8 +897,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
860 buffer_put_int(r, rid); 897 buffer_put_int(r, rid);
861 898
862 free(found_fwd->listen_host); 899 free(found_fwd->listen_host);
900 free(found_fwd->listen_path);
863 free(found_fwd->connect_host); 901 free(found_fwd->connect_host);
902 free(found_fwd->connect_path);
864 found_fwd->listen_host = found_fwd->connect_host = NULL; 903 found_fwd->listen_host = found_fwd->connect_host = NULL;
904 found_fwd->listen_path = found_fwd->connect_path = NULL;
865 found_fwd->listen_port = found_fwd->connect_port = 0; 905 found_fwd->listen_port = found_fwd->connect_port = 0;
866 } else { 906 } else {
867 buffer_put_int(r, MUX_S_FAILURE); 907 buffer_put_int(r, MUX_S_FAILURE);
@@ -870,8 +910,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
870 } 910 }
871 out: 911 out:
872 free(fwd_desc); 912 free(fwd_desc);
873 free(fwd.listen_host); 913 free(listen_addr);
874 free(fwd.connect_host); 914 free(connect_addr);
875 915
876 return ret; 916 return ret;
877} 917}
@@ -1133,8 +1173,6 @@ mux_tty_alloc_failed(Channel *c)
1133void 1173void
1134muxserver_listen(void) 1174muxserver_listen(void)
1135{ 1175{
1136 struct sockaddr_un addr;
1137 socklen_t sun_len;
1138 mode_t old_umask; 1176 mode_t old_umask;
1139 char *orig_control_path = options.control_path; 1177 char *orig_control_path = options.control_path;
1140 char rbuf[16+1]; 1178 char rbuf[16+1];
@@ -1163,23 +1201,10 @@ muxserver_listen(void)
1163 xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); 1201 xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
1164 debug3("%s: temporary control path %s", __func__, options.control_path); 1202 debug3("%s: temporary control path %s", __func__, options.control_path);
1165 1203
1166 memset(&addr, '\0', sizeof(addr));
1167 addr.sun_family = AF_UNIX;
1168 sun_len = offsetof(struct sockaddr_un, sun_path) +
1169 strlen(options.control_path) + 1;
1170
1171 if (strlcpy(addr.sun_path, options.control_path,
1172 sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
1173 error("ControlPath \"%s\" too long for Unix domain socket",
1174 options.control_path);
1175 goto disable_mux_master;
1176 }
1177
1178 if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1179 fatal("%s socket(): %s", __func__, strerror(errno));
1180
1181 old_umask = umask(0177); 1204 old_umask = umask(0177);
1182 if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) { 1205 muxserver_sock = unix_listener(options.control_path, 64, 0);
1206 umask(old_umask);
1207 if (muxserver_sock < 0) {
1183 if (errno == EINVAL || errno == EADDRINUSE) { 1208 if (errno == EINVAL || errno == EADDRINUSE) {
1184 error("ControlSocket %s already exists, " 1209 error("ControlSocket %s already exists, "
1185 "disabling multiplexing", options.control_path); 1210 "disabling multiplexing", options.control_path);
@@ -1193,13 +1218,11 @@ muxserver_listen(void)
1193 options.control_path = NULL; 1218 options.control_path = NULL;
1194 options.control_master = SSHCTL_MASTER_NO; 1219 options.control_master = SSHCTL_MASTER_NO;
1195 return; 1220 return;
1196 } else 1221 } else {
1197 fatal("%s bind(): %s", __func__, strerror(errno)); 1222 /* unix_listener() logs the error */
1223 cleanup_exit(255);
1224 }
1198 } 1225 }
1199 umask(old_umask);
1200
1201 if (listen(muxserver_sock, 64) == -1)
1202 fatal("%s listen(): %s", __func__, strerror(errno));
1203 1226
1204 /* Now atomically "move" the mux socket into position */ 1227 /* Now atomically "move" the mux socket into position */
1205 if (link(options.control_path, orig_control_path) != 0) { 1228 if (link(options.control_path, orig_control_path) != 0) {
@@ -1593,7 +1616,7 @@ mux_client_request_terminate(int fd)
1593} 1616}
1594 1617
1595static int 1618static int
1596mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd) 1619mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
1597{ 1620{
1598 Buffer m; 1621 Buffer m;
1599 char *e, *fwd_desc; 1622 char *e, *fwd_desc;
@@ -1608,11 +1631,19 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
1608 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); 1631 buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
1609 buffer_put_int(&m, muxclient_request_id); 1632 buffer_put_int(&m, muxclient_request_id);
1610 buffer_put_int(&m, ftype); 1633 buffer_put_int(&m, ftype);
1611 buffer_put_cstring(&m, 1634 if (fwd->listen_path != NULL) {
1612 fwd->listen_host == NULL ? "" : fwd->listen_host); 1635 buffer_put_cstring(&m, fwd->listen_path);
1636 } else {
1637 buffer_put_cstring(&m,
1638 fwd->listen_host == NULL ? "" : fwd->listen_host);
1639 }
1613 buffer_put_int(&m, fwd->listen_port); 1640 buffer_put_int(&m, fwd->listen_port);
1614 buffer_put_cstring(&m, 1641 if (fwd->connect_path != NULL) {
1615 fwd->connect_host == NULL ? "" : fwd->connect_host); 1642 buffer_put_cstring(&m, fwd->connect_path);
1643 } else {
1644 buffer_put_cstring(&m,
1645 fwd->connect_host == NULL ? "" : fwd->connect_host);
1646 }
1616 buffer_put_int(&m, fwd->connect_port); 1647 buffer_put_int(&m, fwd->connect_port);
1617 1648
1618 if (mux_client_write_packet(fd, &m) != 0) 1649 if (mux_client_write_packet(fd, &m) != 0)