[PATCH] relayd client certificate validation again

2021-12-16 Thread rivo nurges

Hi!

Here comes the support for relayd client certificate validation.
Full certificate chain, subject and issuer can be passed over in http headers.
It supports mandatory validation and optional validation(if client chooses to
provide certificate it will be validated).

Part of my sample config.

http protocol test {
  match header set "CS_SUBJECT" value "$CLIENT_CERT_SUBJECT"
  match header set "CS_ISSUER" value "$CLIENT_CERT_ISSUER"
  match header set "CS_CERT" value "$CLIENT_CERT_CHAIN"
  pass
  tls {client ca "/tmp/easyrsa3/pki/ca.crt" optional }
}

This uses code from the patches submitted by Ashe Connor.

Rivo

diff refs/heads/master refs/heads/relay-clc3
blob - a2f1c130d6b45e3082048218c11537dca485998a
blob + 5070a7d48f58403f53d818231e1676db749aa9d7
--- usr.sbin/relayd/config.c
+++ usr.sbin/relayd/config.c
@@ -954,6 +954,15 @@ config_setrelay(struct relayd *env, struct relay *rlay
rlay->rl_conf.name);
return (-1);
}
+   if (rlay->rl_tls_client_ca_fd != -1 &&
+   config_setrelayfd(ps, id, n, 0,
+   rlay->rl_conf.id, RELAY_FD_CLIENTCACERT,
+   rlay->rl_tls_client_ca_fd) == -1) {
+   log_warn("%s: fd passing failed for "
+   "`%s'", __func__,
+   rlay->rl_conf.name);
+   return (-1);
+   }
/* Prevent fd exhaustion in the parent. */
if (proc_flush_imsg(ps, id, n) == -1) {
log_warn("%s: failed to flush "
@@ -987,6 +996,10 @@ config_setrelay(struct relayd *env, struct relay *rlay
close(rlay->rl_s);
rlay->rl_s = -1;
}
+   if (rlay->rl_tls_client_ca_fd != -1) {
+   close(rlay->rl_tls_client_ca_fd);
+   rlay->rl_tls_client_ca_fd = -1;
+   }
if (rlay->rl_tls_cacert_fd != -1) {
close(rlay->rl_tls_cacert_fd);
rlay->rl_tls_cacert_fd = -1;
@@ -1012,6 +1025,10 @@ config_setrelay(struct relayd *env, struct relay *rlay
cert->cert_ocsp_fd = -1;
}
}
+   if (rlay->rl_tls_client_ca_fd != -1) {
+   close(rlay->rl_tls_client_ca_fd);
+   rlay->rl_tls_client_ca_fd = -1;
+   }
 
 	return (0);

 }
@@ -1034,6 +1051,7 @@ config_getrelay(struct relayd *env, struct imsg *imsg)
rlay->rl_s = imsg->fd;
rlay->rl_tls_ca_fd = -1;
rlay->rl_tls_cacert_fd = -1;
+   rlay->rl_tls_client_ca_fd = -1;
 
 	if (ps->ps_what[privsep_process] & CONFIG_PROTOS) {

if (rlay->rl_conf.proto == EMPTY_ID)
@@ -1163,6 +1181,9 @@ config_getrelayfd(struct relayd *env, struct imsg *ims
case RELAY_FD_CAFILE:
rlay->rl_tls_cacert_fd = imsg->fd;
break;
+   case RELAY_FD_CLIENTCACERT:
+   rlay->rl_tls_client_ca_fd = imsg->fd;
+   break;
}
 
 	DPRINTF("%s: %s %d received relay fd %d type %d for relay %s", __func__,

blob - 22beb857229a16e5b2c17a25a2944231d41e7e08
blob + fe5e8ff4dfed10e8f09e3226bdfe33f8bc031c8e
--- usr.sbin/relayd/parse.y
+++ usr.sbin/relayd/parse.y
@@ -172,14 +172,14 @@ typedef struct {
 %token CODE COOKIE DEMOTE DIGEST DISABLE ERROR EXPECT PASS BLOCK EXTERNAL
 %token FILENAME FORWARD FROM HASH HEADER HEADERLEN HOST HTTP ICMP INCLUDE INET
 %token INET6 INTERFACE INTERVAL IP KEYPAIR LABEL LISTEN VALUE LOADBALANCE LOG
-%token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
+%token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON OPTIONAL 
PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
 %token SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED TCP
 %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
-%token WEBSOCKETS
+%token WEBSOCKETS CLIENT
 %token STRING
 %token NUMBER
 %type  context hostname interface table value path
@@ -188,6 +188,7 @@ typedef struct {
 %type  opttls opttlsclient
 %type  redirect_proto relay_proto match
 %type  action ruleaf key_option
+%type  clientcaopt
 %typeport
 %typehost
 %typeaddress rulesrc ruledst addrprefix
@@ -244,6 +245,10 @@ opttlsclient   : /*empty*/ { $$ = 0; }
| WITH ssltls   { $$ = 1; }
;
 
+clientcaopt	: /*empty*/ { $$ = 0; }

+   | 

relayd client certificate validation

2021-05-23 Thread rivo nurges

Hi!

Here comes the support for relayd client certificate validation.
Full certificate chain, subject and issuer can be passed over in http headers.
It supports mandatory validation, optional validation(if client chooses to
provide certificate it will be validated) and no validation(cert is passed to
the backend but no validation will happen in relayd).

Part of my sample config.

http protocol test {
  match header set "CS_SUBJECT" value "$CLIENT_CERT_SUBJECT"
  match header set "CS_ISSUER" value "$CLIENT_CERT_ISSUER"
  match header set "CS_CERT" value "$CLIENT_CERT_CHAIN"
  pass
  tls client ca "/tmp/easyrsa3/pki/ca.crt"
  tls { client-insecure, client-optional }
}

This uses code from the patches submitted by Ashe Connor.

Rivo

diff 8c17c73d13a081367dafe608a20fbe1b0ed903ce /home/rix/src
blob - 3e60d63ef52437fed245ed2715e30a0b2bf7956b
file + usr.sbin/relayd/config.c
--- usr.sbin/relayd/config.c
+++ usr.sbin/relayd/config.c
@@ -956,6 +956,15 @@ config_setrelay(struct relayd *env, struct relay *rlay
rlay->rl_conf.name);
return (-1);
}
+   if (rlay->rl_tls_client_ca_fd != -1 &&
+   config_setrelayfd(ps, id, n, 0,
+   rlay->rl_conf.id, RELAY_FD_CLIENTCACERT,
+   rlay->rl_tls_client_ca_fd) == -1) {
+   log_warn("%s: fd passing failed for "
+   "`%s'", __func__,
+   rlay->rl_conf.name);
+   return (-1);
+   }
/* Prevent fd exhaustion in the parent. */
if (proc_flush_imsg(ps, id, n) == -1) {
log_warn("%s: failed to flush "
@@ -989,6 +998,10 @@ config_setrelay(struct relayd *env, struct relay *rlay
close(rlay->rl_s);
rlay->rl_s = -1;
}
+   if (rlay->rl_tls_client_ca_fd != -1) {
+   close(rlay->rl_tls_client_ca_fd);
+   rlay->rl_tls_client_ca_fd = -1;
+   }
if (rlay->rl_tls_cacert_fd != -1) {
close(rlay->rl_tls_cacert_fd);
rlay->rl_tls_cacert_fd = -1;
@@ -1014,6 +1027,10 @@ config_setrelay(struct relayd *env, struct relay *rlay
cert->cert_ocsp_fd = -1;
}
}
+   if (rlay->rl_tls_client_ca_fd != -1) {
+   close(rlay->rl_tls_client_ca_fd);
+   rlay->rl_tls_client_ca_fd = -1;
+   }
 
 	return (0);

 }
@@ -1036,6 +1053,7 @@ config_getrelay(struct relayd *env, struct imsg *imsg)
rlay->rl_s = imsg->fd;
rlay->rl_tls_ca_fd = -1;
rlay->rl_tls_cacert_fd = -1;
+   rlay->rl_tls_client_ca_fd = -1;
 
 	if (ps->ps_what[privsep_process] & CONFIG_PROTOS) {

if (rlay->rl_conf.proto == EMPTY_ID)
@@ -1165,6 +1183,9 @@ config_getrelayfd(struct relayd *env, struct imsg *ims
case RELAY_FD_CAFILE:
rlay->rl_tls_cacert_fd = imsg->fd;
break;
+   case RELAY_FD_CLIENTCACERT:
+   rlay->rl_tls_client_ca_fd = imsg->fd;
+   break;
}
 
 	DPRINTF("%s: %s %d received relay fd %d type %d for relay %s", __func__,

blob - 5f7513e788d7ba0615942bd1efee8d9cff6e9941
file + usr.sbin/relayd/parse.y
--- usr.sbin/relayd/parse.y
+++ usr.sbin/relayd/parse.y
@@ -179,7 +179,7 @@ typedef struct {
 %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
-%token WEBSOCKETS
+%token WEBSOCKETS CLIENT
 %token STRING
 %token NUMBER
 %type  context hostname interface table value path
@@ -1353,6 +1353,16 @@ tlsflags : SESSION TICKETS { proto->tickets = 1; }
name->name = $2;
TAILQ_INSERT_TAIL(>tlscerts, name, entry);
}
+   | CLIENT CA STRING  {
+   if (strlcpy(proto->tlsclientca, $3,
+   sizeof(proto->tlsclientca)) >=
+   sizeof(proto->tlsclientca)) {
+   yyerror("tlsclientca truncated");
+   free($3);
+   YYERROR;
+   }
+   free($3);
+   }
| NO flag   { proto->tlsflags &= ~($2); }
| flag  { proto->tlsflags |= $1; }
;
@@ -1374,6 +1384,10 @@ flag : STRING{
$$ = TLSFLAG_CIPHER_SERVER_PREF;
   

fix bgpd route-reflector without cluster id

2019-09-26 Thread Rivo Nurges
Hi!

Before bgpd.c:1.225 bgpd ran merge_config on startup and set the cluster-id to 
router-id when needed. This is not the case anymore and if 
cluster-id is not explicitly specified its not picked up on startup causing bgp 
to use 0.0.0.0 as the cluster-id.

Rivo

Index: usr.sbin/bgpd/config.c
===
RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
retrieving revision 1.92
diff -u -p -r1.92 config.c
--- usr.sbin/bgpd/config.c  13 Aug 2019 07:39:57 -  1.92
+++ usr.sbin/bgpd/config.c  26 Sep 2019 19:28:21 -
@@ -201,8 +201,6 @@ merge_config(struct bgpd_config *xconf,
/*
 * merge the freshly parsed conf into the running xconf
 */
-   if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
-   conf->clusterid = conf->bgpid;

/* adjust FIB priority if changed */
/* if xconf is uninitialized we get RTP_NONE */
Index: usr.sbin/bgpd/parse.y
===
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.401
diff -u -p -r1.401 parse.y
--- usr.sbin/bgpd/parse.y   13 Aug 2019 07:39:57 -  1.401
+++ usr.sbin/bgpd/parse.y   26 Sep 2019 19:28:21 -
@@ -3309,6 +3309,8 @@ parse_config(char *filename, struct peer
log_warnx("configuration error: AS not given");
errors++;
}
+   if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
+   conf->clusterid = conf->bgpid;

/* clear the globals */
curpeer = NULL;



Re: relayd websocket

2019-05-08 Thread Rivo Nurges
Hi!

Seems to work fine.

Rivo

On 2019-05-08 21:37, Reyk Floeter wrote:
> On Wed, May 08, 2019 at 07:07:43PM +0200, Reyk Floeter wrote:
>> On Wed, May 08, 2019 at 06:26:45PM +0200, Reyk Floeter wrote:
>>> On Wed, Mar 06, 2019 at 05:36:32PM +0100, Sebastian Benoit wrote:
>>>> Rivo Nurges(rivo.nur...@smit.ee) on 2019.03.05 22:42:13 +:
>>>>> Hi!
>>>>>
>>>>> On 3/5/19 10:36 PM, Claudio Jeker wrote:
>>>>>> I guess that this would need strcasestr() instead of strcasecmp(), since 
>>>>>> you
>>>>>> are looking for the substring "Upgrade" in value. Maybe more is needed if
>>>>>> we want to be sure that 'Connection: Upgrade-maybe' does not match.
>>>>>
>>>>> You are correct about strcasestr. "Connection: Upgrade-maybe" would need
>>>>> to have correct "Upgrade: websocket". Anyway, lets be strict.
>>>>>
>>>>> Does something like this make sense?
>>>>
>>>> i think the seperator list needs to include '\t'
>>>> because https://tools.ietf.org/html/rfc7230#appendix-B includes HTAB.
>>>>
>>>> And i dont think you can mix "," with " \t" seperators,
>>>> because otherwise "Foo Upgrade, Bar" will match.
>>>>
>>>> Something more is needed to parse elements of a header.
>>>>   
>>>
>>> I would reshuffle the websocket handling a bit as I don't think that
>>> we need the http priv struct.  We can lookup the parsed headers later.
>>>
>>> The attached diff moves it all into one places and introduces a new
>>> function kv_find_value() that is able to to match headers with
>>> multiple values (I think we might need it elsewhere.  And even if not,
>>> I would prefer to have this in a function intead of stuffing it into
>>> relay_read_http).
>>>
>>> A minor question is if the lookup should be done before or after
>>> applying the filters (relay_test - my diff does it afterwards, the
>>> current code does it before).
>>>
>>> Tests?  Comments?  Ok?
>>>
>>
>> I keep on replying to my own diffs...  the updated one below uses
>> strcasecmp instead of strcasestr in kv_find_value().  There is no need
>> for substring- or fn- matching in this function.
>>
> 
> Next one...
> 
> benno@ pointed out that the RFC allows whitespace before the comma.
> We also don't have to strip \r\n as it is done by relayd's kv parser.
> 
> OK?
> 
> Reyk
> 
> Index: usr.sbin/relayd/http.h
> ===
> RCS file: /cvs/src/usr.sbin/relayd/http.h,v
> retrieving revision 1.10
> diff -u -p -u -p -r1.10 http.h
> --- usr.sbin/relayd/http.h4 Mar 2019 21:25:03 -   1.10
> +++ usr.sbin/relayd/http.h8 May 2019 18:34:09 -
> @@ -251,10 +251,4 @@ struct http_descriptor {
>   struct kvtreehttp_headers;
>   };
>   
> -struct relay_http_priv {
> -#define HTTP_CONNECTION_UPGRADE  0x01
> -#define HTTP_UPGRADE_WEBSOCKET   0x02
> - int  http_upgrade_req;
> -};
> -
>   #endif /* HTTP_H */
> Index: usr.sbin/relayd/relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.242
> diff -u -p -u -p -r1.242 relay.c
> --- usr.sbin/relayd/relay.c   4 Mar 2019 21:25:03 -   1.242
> +++ usr.sbin/relayd/relay.c   8 May 2019 18:34:09 -
> @@ -1410,13 +1410,7 @@ relay_session(struct rsession *con)
>   return;
>   }
>   
> - if (rlay->rl_proto->type == RELAY_PROTO_HTTP) {
> - if (relay_http_priv_init(con) == -1) {
> - relay_close(con,
> - "failed to allocate http session data", 1);
> - return;
> - }
> - } else {
> + if (rlay->rl_proto->type != RELAY_PROTO_HTTP) {
>   if (rlay->rl_conf.fwdmode == FWD_TRANS)
>   relay_bindanyreq(con, 0, IPPROTO_TCP);
>   else if (relay_connect(con) == -1) {
> Index: usr.sbin/relayd/relay_http.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
> retrieving revision 1.72
> diff -u -p -u -p -r1.72 relay_http.c
> --- usr.sbin/relayd/relay_http.c  4 Mar 2019 21:25:03 -   1.72
> +++ usr.sbin/relayd/relay_http.c  8 May 2019 18:34:09 -
> @@ -110,17 

Re: relayd websocket

2019-05-08 Thread Rivo Nurges
Hi!

Anyone?

Rivo

On 2019-03-12 21:50, Rivo Nurges wrote:
> Hi!
> 
> Bump...
> 
> Rivo
> 
> On 3/6/19 10:57 PM, Rivo Nurges wrote:
>> Hi!
>>
>>
>> On 3/6/19 10:20 PM, Rivo Nurges wrote:
>>> On 3/6/19 6:36 PM, Sebastian Benoit wrote:
>>>>> Does something like this make sense?
>>>>
>>>> i think the seperator list needs to include '\t'
>>>> because https://tools.ietf.org/html/rfc7230#appendix-B includes HTAB.
>>>>
>>>> And i dont think you can mix "," with " \t" seperators,
>>>> because otherwise "Foo Upgrade, Bar" will match.
>>>>
>>>> Something more is needed to parse elements of a header.
>>>
>>> Oh yeah. I'll work on that.
>>
>> So here comes the next version. Works with both spaces and tabs.
>>
>> Index: usr.sbin/relayd/relay_http.c
>> ===
>> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
>> retrieving revision 1.72
>> diff -u -p -r1.72 relay_http.c
>> --- usr.sbin/relayd/relay_http.c 4 Mar 2019 21:25:03 -   1.72
>> +++ usr.sbin/relayd/relay_http.c 6 Mar 2019 20:53:59 -
>> @@ -36,6 +36,7 @@
>> #include 
>> #include 
>> #include 
>> +#include 
>>
>> #include "relayd.h"
>> #include "http.h"
>> @@ -166,6 +167,7 @@ relay_read_http(struct bufferevent *bev,
>>  struct relay_http_priv  *priv = con->se_priv;
>>  char*line = NULL, *key, *value;
>>  char*urlproto, *host, *path;
>> +char*valuecopy, *valuepart;
>>  int  action, unique, ret;
>>  const char  *errstr;
>>  size_t   size, linelen;
>> @@ -399,10 +401,19 @@ relay_read_http(struct bufferevent *bev,
>>
>>  if (cre->line != 1) {
>>  if (cre->dir == RELAY_DIR_REQUEST) {
>> -if (strcasecmp("Connection", key) == 0 &&
>> -strcasecmp("Upgrade", value) == 0)
>> -priv->http_upgrade_req |=
>> -HTTP_CONNECTION_UPGRADE;
>> +if (strcasecmp("Connection", key) == 0) {
>> +valuecopy = strdup(value);
>> +while ((valuepart = strsep(,
>> +",")) != NULL) {
>> +while (isblank(*valuepart))
>> +valuepart = [1];
>> +if (strcasecmp("Upgrade", valuepart)
>> +== 0)
>> +priv->http_upgrade_req |=
>> +HTTP_CONNECTION_UPGRADE;
>> +}
>> +free(valuecopy);
>> +}
>>  if (strcasecmp("Upgrade", key) == 0 &&
>>  strcasecmp("websocket", value) == 0)
>>  priv->http_upgrade_req |=
>>
>>
>> begin-base64 644 websocket3.diff
>> SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
>> PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
>> L2N2cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
>> b24gMS43MgpkaWZmIC11IC1wIC1yMS43MiByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5
>> ZC9yZWxheV9odHRwLmMJNCBNYXIgMjAxOSAyMToyNTowMyAtMDAwMAkxLjcyCisrKyB1c3Iuc2Jp
>> bi9yZWxheWQvcmVsYXlfaHR0cC5jCTYgTWFyIDIwMTkgMjA6NTM6NTkgLTAwMDAKQEAgLTM2LDYg
>> KzM2LDcgQEAKICNpbmNsdWRlIDxzaXBoYXNoLmg+CiAjaW5jbHVkZSA8aW1zZy5oPgogI2luY2x1
>> ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGN0eXBlLmg+CiAKICNpbmNsdWRlICJyZWxheWQuaCIK
>> ICNpbmNsdWRlICJodHRwLmgiCkBAIC0xNjYsNiArMTY3LDcgQEAgcmVsYXlfcmVhZF9odHRwKHN0
>> cnVjdCBidWZmZXJldmVudCAqYmV2LAogCXN0cnVjdCByZWxheV9odHRwX3ByaXYJKnByaXYgPSBj
>> b24tPnNlX3ByaXY7CiAJY2hhcgkJCSpsaW5lID0gTlVMTCwgKmtleSwgKnZhbHVlOwogCWNoYXIJ
>> CQkqdXJscHJvdG8sICpob3N0LCAqcGF0aDsKKwljaGFyCQkJKnZhbHVlY29weSwgKnZhbHVlcGFy
>> dDsKIAlpbnQJCQkgYWN0aW9uLCB1bmlxdWUsIHJldDsKIAljb25zdCBjaGFyCQkqZXJyc3RyOwog
>> CXNpemVfdAkJCSBzaXplLCBsaW5lbGVuOwpAQCAtMzk5LDEwICs0MDEsM

Re: relayd(8) websockets proxy broken after adding websockets support

2019-04-12 Thread Rivo Nurges
Hi!

I previously proposed following.

https://marc.info/?l=openbsd-tech=155190594005692=2

Rivo

On 4/10/19 2:38 PM, Pavel Korovin wrote:
> Dear all,
> 
> After websockets support was added in relayd(8),
> https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/relayd/relay_http.c.diff?r1=1.71=1.72=h
> the connections to services usging websockets are broken.
> 
> I checked what caused this breakage, and found that the check for the
> "Connection" HTTP request header strictly checks for "Upgrade" value (line 
> 402):
> 
> if (cre->dir == RELAY_DIR_REQUEST) {
>   if (strcasecmp("Connection", key) == 0 &&
>   strcasecmp("Upgrade", value) == 0)
>   priv->http_upgrade_req |=
>   HTTP_CONNECTION_UPGRADE;
> 
> while the browser can also send (and sends)
>   Connection: keep-alive, Upgrade
> 
> Websockets work fine if I add keep-alive to the list of values, but I'm sure
> this must be fixed in some other way,
> 
> --- usr.sbin/relayd/relay_http.c.orig   Wed Apr  3 17:41:00 2019
> +++ usr.sbin/relayd/relay_http.cWed Apr  3 21:31:37 2019
> @@ -400,7 +400,8 @@
>  if (cre->line != 1) {
>  if (cre->dir == RELAY_DIR_REQUEST) {
>  if (strcasecmp("Connection", key) == 0 &&
> -   strcasecmp("Upgrade", value) == 0)
> +  (strcasecmp("Upgrade", value) == 0 ||
> +  strcasecmp("keep-alive, Upgrade", value) 
> == 0))
>  priv->http_upgrade_req |=
>  HTTP_CONNECTION_UPGRADE;
>  if (strcasecmp("Upgrade", key) == 0 &&
> 



Re: relayd websocket

2019-03-12 Thread Rivo Nurges
Hi!

Bump...

Rivo

On 3/6/19 10:57 PM, Rivo Nurges wrote:
> Hi!
> 
> 
> On 3/6/19 10:20 PM, Rivo Nurges wrote:
>> On 3/6/19 6:36 PM, Sebastian Benoit wrote:
>>>> Does something like this make sense?
>>>
>>> i think the seperator list needs to include '\t'
>>> because https://tools.ietf.org/html/rfc7230#appendix-B includes HTAB.
>>>
>>> And i dont think you can mix "," with " \t" seperators,
>>> because otherwise "Foo Upgrade, Bar" will match.
>>>
>>> Something more is needed to parse elements of a header.
>>
>> Oh yeah. I'll work on that.
> 
> So here comes the next version. Works with both spaces and tabs.
> 
> Index: usr.sbin/relayd/relay_http.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 relay_http.c
> --- usr.sbin/relayd/relay_http.c  4 Mar 2019 21:25:03 -   1.72
> +++ usr.sbin/relayd/relay_http.c  6 Mar 2019 20:53:59 -
> @@ -36,6 +36,7 @@
>#include 
>#include 
>#include 
> +#include 
> 
>#include "relayd.h"
>#include "http.h"
> @@ -166,6 +167,7 @@ relay_read_http(struct bufferevent *bev,
>   struct relay_http_priv  *priv = con->se_priv;
>   char*line = NULL, *key, *value;
>   char*urlproto, *host, *path;
> + char*valuecopy, *valuepart;
>   int  action, unique, ret;
>   const char  *errstr;
>   size_t   size, linelen;
> @@ -399,10 +401,19 @@ relay_read_http(struct bufferevent *bev,
> 
>   if (cre->line != 1) {
>   if (cre->dir == RELAY_DIR_REQUEST) {
> - if (strcasecmp("Connection", key) == 0 &&
> - strcasecmp("Upgrade", value) == 0)
> - priv->http_upgrade_req |=
> - HTTP_CONNECTION_UPGRADE;
> + if (strcasecmp("Connection", key) == 0) {
> + valuecopy = strdup(value);
> + while ((valuepart = strsep(,
> + ",")) != NULL) {
> + while (isblank(*valuepart))
> + valuepart = [1];
> + if (strcasecmp("Upgrade", valuepart)
> + == 0)
> + priv->http_upgrade_req |=
> + HTTP_CONNECTION_UPGRADE;
> + }
> + free(valuecopy);
> + }
>   if (strcasecmp("Upgrade", key) == 0 &&
>   strcasecmp("websocket", value) == 0)
>   priv->http_upgrade_req |=
> 
> 
> begin-base64 644 websocket3.diff
> SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
> PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
> L2N2cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
> b24gMS43MgpkaWZmIC11IC1wIC1yMS43MiByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5
> ZC9yZWxheV9odHRwLmMJNCBNYXIgMjAxOSAyMToyNTowMyAtMDAwMAkxLjcyCisrKyB1c3Iuc2Jp
> bi9yZWxheWQvcmVsYXlfaHR0cC5jCTYgTWFyIDIwMTkgMjA6NTM6NTkgLTAwMDAKQEAgLTM2LDYg
> KzM2LDcgQEAKICNpbmNsdWRlIDxzaXBoYXNoLmg+CiAjaW5jbHVkZSA8aW1zZy5oPgogI2luY2x1
> ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGN0eXBlLmg+CiAKICNpbmNsdWRlICJyZWxheWQuaCIK
> ICNpbmNsdWRlICJodHRwLmgiCkBAIC0xNjYsNiArMTY3LDcgQEAgcmVsYXlfcmVhZF9odHRwKHN0
> cnVjdCBidWZmZXJldmVudCAqYmV2LAogCXN0cnVjdCByZWxheV9odHRwX3ByaXYJKnByaXYgPSBj
> b24tPnNlX3ByaXY7CiAJY2hhcgkJCSpsaW5lID0gTlVMTCwgKmtleSwgKnZhbHVlOwogCWNoYXIJ
> CQkqdXJscHJvdG8sICpob3N0LCAqcGF0aDsKKwljaGFyCQkJKnZhbHVlY29weSwgKnZhbHVlcGFy
> dDsKIAlpbnQJCQkgYWN0aW9uLCB1bmlxdWUsIHJldDsKIAljb25zdCBjaGFyCQkqZXJyc3RyOwog
> CXNpemVfdAkJCSBzaXplLCBsaW5lbGVuOwpAQCAtMzk5LDEwICs0MDEsMTkgQEAgcmVsYXlfcmVh
> ZF9odHRwKHN0cnVjdCBidWZmZXJldmVudCAqYmV2LAogCiAJCWlmIChjcmUtPmxpbmUgIT0gMSkg
> ewogCQkJaWYgKGNyZS0+ZGlyID09IFJFTEFZX0RJUl9SRVFVRVNUKSB7Ci0JCQkJaWYgKHN0cmNh
> c2VjbXAoIkNvbm5lY3Rpb24iLCBrZXkpID09IDAgJiYKLQkJCQkgICAgc3RyY2FzZWNtcCgiVXBn
> cmFkZSIsIHZhbHVlKSA9PSAwKQotCQkJCQlwcml2LT5odHRwX3VwZ3JhZGVfcmVxIHw9C

Re: relayd websocket

2019-03-06 Thread Rivo Nurges
Hi!


On 3/6/19 10:20 PM, Rivo Nurges wrote:
> On 3/6/19 6:36 PM, Sebastian Benoit wrote:
>>> Does something like this make sense?
>>
>> i think the seperator list needs to include '\t'
>> because https://tools.ietf.org/html/rfc7230#appendix-B includes HTAB.
>>
>> And i dont think you can mix "," with " \t" seperators,
>> because otherwise "Foo Upgrade, Bar" will match.
>>
>> Something more is needed to parse elements of a header.
> 
> Oh yeah. I'll work on that.

So here comes the next version. Works with both spaces and tabs.

Index: usr.sbin/relayd/relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.72
diff -u -p -r1.72 relay_http.c
--- usr.sbin/relayd/relay_http.c4 Mar 2019 21:25:03 -   1.72
+++ usr.sbin/relayd/relay_http.c6 Mar 2019 20:53:59 -
@@ -36,6 +36,7 @@
  #include 
  #include 
  #include 
+#include 

  #include "relayd.h"
  #include "http.h"
@@ -166,6 +167,7 @@ relay_read_http(struct bufferevent *bev,
struct relay_http_priv  *priv = con->se_priv;
char*line = NULL, *key, *value;
char*urlproto, *host, *path;
+   char*valuecopy, *valuepart;
int  action, unique, ret;
const char  *errstr;
size_t   size, linelen;
@@ -399,10 +401,19 @@ relay_read_http(struct bufferevent *bev,

if (cre->line != 1) {
if (cre->dir == RELAY_DIR_REQUEST) {
-   if (strcasecmp("Connection", key) == 0 &&
-   strcasecmp("Upgrade", value) == 0)
-   priv->http_upgrade_req |=
-   HTTP_CONNECTION_UPGRADE;
+   if (strcasecmp("Connection", key) == 0) {
+   valuecopy = strdup(value);
+   while ((valuepart = strsep(,
+   ",")) != NULL) {
+   while (isblank(*valuepart))
+   valuepart = [1];
+   if (strcasecmp("Upgrade", valuepart)
+   == 0)
+   priv->http_upgrade_req |=
+   HTTP_CONNECTION_UPGRADE;
+   }
+   free(valuecopy);
+   }
if (strcasecmp("Upgrade", key) == 0 &&
strcasecmp("websocket", value) == 0)
priv->http_upgrade_req |=


begin-base64 644 websocket3.diff
SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS43MgpkaWZmIC11IC1wIC1yMS43MiByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5
ZC9yZWxheV9odHRwLmMJNCBNYXIgMjAxOSAyMToyNTowMyAtMDAwMAkxLjcyCisrKyB1c3Iuc2Jp
bi9yZWxheWQvcmVsYXlfaHR0cC5jCTYgTWFyIDIwMTkgMjA6NTM6NTkgLTAwMDAKQEAgLTM2LDYg
KzM2LDcgQEAKICNpbmNsdWRlIDxzaXBoYXNoLmg+CiAjaW5jbHVkZSA8aW1zZy5oPgogI2luY2x1
ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPGN0eXBlLmg+CiAKICNpbmNsdWRlICJyZWxheWQuaCIK
ICNpbmNsdWRlICJodHRwLmgiCkBAIC0xNjYsNiArMTY3LDcgQEAgcmVsYXlfcmVhZF9odHRwKHN0
cnVjdCBidWZmZXJldmVudCAqYmV2LAogCXN0cnVjdCByZWxheV9odHRwX3ByaXYJKnByaXYgPSBj
b24tPnNlX3ByaXY7CiAJY2hhcgkJCSpsaW5lID0gTlVMTCwgKmtleSwgKnZhbHVlOwogCWNoYXIJ
CQkqdXJscHJvdG8sICpob3N0LCAqcGF0aDsKKwljaGFyCQkJKnZhbHVlY29weSwgKnZhbHVlcGFy
dDsKIAlpbnQJCQkgYWN0aW9uLCB1bmlxdWUsIHJldDsKIAljb25zdCBjaGFyCQkqZXJyc3RyOwog
CXNpemVfdAkJCSBzaXplLCBsaW5lbGVuOwpAQCAtMzk5LDEwICs0MDEsMTkgQEAgcmVsYXlfcmVh
ZF9odHRwKHN0cnVjdCBidWZmZXJldmVudCAqYmV2LAogCiAJCWlmIChjcmUtPmxpbmUgIT0gMSkg
ewogCQkJaWYgKGNyZS0+ZGlyID09IFJFTEFZX0RJUl9SRVFVRVNUKSB7Ci0JCQkJaWYgKHN0cmNh
c2VjbXAoIkNvbm5lY3Rpb24iLCBrZXkpID09IDAgJiYKLQkJCQkgICAgc3RyY2FzZWNtcCgiVXBn
cmFkZSIsIHZhbHVlKSA9PSAwKQotCQkJCQlwcml2LT5odHRwX3VwZ3JhZGVfcmVxIHw9Ci0JCQkJ
CSAgICBIVFRQX0NPTk5FQ1RJT05fVVBHUkFERTsKKwkJCQlpZiAoc3RyY2FzZWNtcCgiQ29ubmVj
dGlvbiIsIGtleSkgPT0gMCkgeworCQkJCSAgICB2YWx1ZWNvcHkgPSBzdHJkdXAodmFsdWUpOwor
CQkJCSAgICB3aGlsZSAoKHZhbHVlcGFydCA9IHN0cnNlcCgmdmFsdWVjb3B5LAorCQkJCQkiLCIp
KSAhPSBOVUxMKSB7CisJCQkJCXdoaWxlIChpc2JsYW5rKCp2YWx1ZXBhcnQpKQorCQkJCQkgICAg
dmFsdWVwYXJ0ID0gJnZhbHVlcGFydFsxXTsKKwkJCQkgICAgCWlmIChzdHJjYXNlY21wKCJVcGdy
YWRlIiwgdmFsdWVwYXJ0KQorCQkJCQkgICAgPT0gMCkKKwkJCQkJICAgIHByaXYtPmh0dHBfdXBn
cmFkZV9yZX

Re: relayd websocket

2019-03-06 Thread Rivo Nurges
On 3/6/19 6:36 PM, Sebastian Benoit wrote:
>> Does something like this make sense?
> 
> i think the seperator list needs to include '\t'
> because https://tools.ietf.org/html/rfc7230#appendix-B includes HTAB.
> 
> And i dont think you can mix "," with " \t" seperators,
> because otherwise "Foo Upgrade, Bar" will match.
> 
> Something more is needed to parse elements of a header.

Oh yeah. I'll work on that.

Rivo



Re: relayd websocket

2019-03-05 Thread Rivo Nurges
Hi!

On 3/5/19 10:36 PM, Claudio Jeker wrote:
> I guess that this would need strcasestr() instead of strcasecmp(), since you
> are looking for the substring "Upgrade" in value. Maybe more is needed if
> we want to be sure that 'Connection: Upgrade-maybe' does not match.

You are correct about strcasestr. "Connection: Upgrade-maybe" would need 
to have correct "Upgrade: websocket". Anyway, lets be strict.

Does something like this make sense?

Index: usr.sbin/relayd/relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.72
diff -u -p -r1.72 relay_http.c
--- usr.sbin/relayd/relay_http.c4 Mar 2019 21:25:03 -   1.72
+++ usr.sbin/relayd/relay_http.c5 Mar 2019 22:33:47 -
@@ -166,6 +166,7 @@ relay_read_http(struct bufferevent *bev,
struct relay_http_priv  *priv = con->se_priv;
char*line = NULL, *key, *value;
char*urlproto, *host, *path;
+   char*valuecopy, *valuepart;
int  action, unique, ret;
const char  *errstr;
size_t   size, linelen;
@@ -399,10 +400,18 @@ relay_read_http(struct bufferevent *bev,

if (cre->line != 1) {
if (cre->dir == RELAY_DIR_REQUEST) {
-   if (strcasecmp("Connection", key) == 0 &&
-   strcasecmp("Upgrade", value) == 0)
-   priv->http_upgrade_req |=
-   HTTP_CONNECTION_UPGRADE;
+
+
+   if (strcasecmp("Connection", key) == 0) {
+   valuecopy = strdup(value);
+   while ((valuepart = strsep(, ", 
")) != NULL)
+   if (strcasecmp("Upgrade", valuepart) == 
0)
+   priv->http_upgrade_req |=
+   HTTP_CONNECTION_UPGRADE;
+   free(valuecopy);
+   }
+
+
if (strcasecmp("Upgrade", key) == 0 &&
strcasecmp("websocket", value) == 0)
priv->http_upgrade_req |=



begin-base64 644 websocket2.diff
SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS43MgpkaWZmIC11IC1wIC1yMS43MiByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5
ZC9yZWxheV9odHRwLmMJNCBNYXIgMjAxOSAyMToyNTowMyAtMDAwMAkxLjcyCisrKyB1c3Iuc2Jp
bi9yZWxheWQvcmVsYXlfaHR0cC5jCTUgTWFyIDIwMTkgMjI6MzM6NDcgLTAwMDAKQEAgLTE2Niw2
ICsxNjYsNyBAQCByZWxheV9yZWFkX2h0dHAoc3RydWN0IGJ1ZmZlcmV2ZW50ICpiZXYsCiAJc3Ry
dWN0IHJlbGF5X2h0dHBfcHJpdgkqcHJpdiA9IGNvbi0+c2VfcHJpdjsKIAljaGFyCQkJKmxpbmUg
PSBOVUxMLCAqa2V5LCAqdmFsdWU7CiAJY2hhcgkJCSp1cmxwcm90bywgKmhvc3QsICpwYXRoOwor
CWNoYXIJCQkqdmFsdWVjb3B5LCAqdmFsdWVwYXJ0OwogCWludAkJCSBhY3Rpb24sIHVuaXF1ZSwg
cmV0OwogCWNvbnN0IGNoYXIJCSplcnJzdHI7CiAJc2l6ZV90CQkJIHNpemUsIGxpbmVsZW47CkBA
IC0zOTksMTAgKzQwMCwxOCBAQCByZWxheV9yZWFkX2h0dHAoc3RydWN0IGJ1ZmZlcmV2ZW50ICpi
ZXYsCiAKIAkJaWYgKGNyZS0+bGluZSAhPSAxKSB7CiAJCQlpZiAoY3JlLT5kaXIgPT0gUkVMQVlf
RElSX1JFUVVFU1QpIHsKLQkJCQlpZiAoc3RyY2FzZWNtcCgiQ29ubmVjdGlvbiIsIGtleSkgPT0g
MCAmJgotCQkJCSAgICBzdHJjYXNlY21wKCJVcGdyYWRlIiwgdmFsdWUpID09IDApCi0JCQkJCXBy
aXYtPmh0dHBfdXBncmFkZV9yZXEgfD0KLQkJCQkJICAgIEhUVFBfQ09OTkVDVElPTl9VUEdSQURF
OworCisKKwkJCQlpZiAoc3RyY2FzZWNtcCgiQ29ubmVjdGlvbiIsIGtleSkgPT0gMCkgeworCQkJ
CSAgICB2YWx1ZWNvcHkgPSBzdHJkdXAodmFsdWUpOworCQkJCSAgICB3aGlsZSAoKHZhbHVlcGFy
dCA9IHN0cnNlcCgmdmFsdWVjb3B5LCAiLCAiKSkgIT0gTlVMTCkKKwkJCQkgICAgCWlmIChzdHJj
YXNlY21wKCJVcGdyYWRlIiwgdmFsdWVwYXJ0KSA9PSAwKQorCQkJCQkgICAgcHJpdi0+aHR0cF91
cGdyYWRlX3JlcSB8PQorCQkJCQkgICAgCUhUVFBfQ09OTkVDVElPTl9VUEdSQURFOworCQkJCSAg
ICBmcmVlKHZhbHVlY29weSk7CisJCQkJfQorCisKIAkJCQlpZiAoc3RyY2FzZWNtcCgiVXBncmFk
ZSIsIGtleSkgPT0gMCAmJgogCQkJCSAgICBzdHJjYXNlY21wKCJ3ZWJzb2NrZXQiLCB2YWx1ZSkg
PT0gMCkKIAkJCQkJcHJpdi0+aHR0cF91cGdyYWRlX3JlcSB8PQo=









relayd websocket

2019-03-05 Thread Rivo Nurges
Hi!

RFC 6455 4.2.1 states:
4.   A |Connection| header field that *includes* the token "Upgrade",
  treated as an ASCII case-insensitive value.

In my test case Firefox sends: Connection: keep-alive, Upgrade

Relayd currently expects Connection to equal Upgrade, not include Upgrade.

I haven't figured out how to configure Thunderbird to send proper diffs, 
so I'm sending bas64 encoded version too.

Index: usr.sbin/relayd/relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.72
diff -u -p -r1.72 relay_http.c
--- usr.sbin/relayd/relay_http.c4 Mar 2019 21:25:03 -   1.72
+++ usr.sbin/relayd/relay_http.c5 Mar 2019 16:03:56 -
@@ -400,7 +400,7 @@ relay_read_http(struct bufferevent *bev,
if (cre->line != 1) {
if (cre->dir == RELAY_DIR_REQUEST) {
if (strcasecmp("Connection", key) == 0 &&
-   strcasecmp("Upgrade", value) == 0)
+   strcasecmp("Upgrade", value) >= 0)
priv->http_upgrade_req |=
HTTP_CONNECTION_UPGRADE;
if (strcasecmp("Upgrade", key) == 0 &&


begin-base64 644 websocket.diff
SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS43MgpkaWZmIC11IC1wIC1yMS43MiByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5
ZC9yZWxheV9odHRwLmMJNCBNYXIgMjAxOSAyMToyNTowMyAtMDAwMAkxLjcyCisrKyB1c3Iuc2Jp
bi9yZWxheWQvcmVsYXlfaHR0cC5jCTUgTWFyIDIwMTkgMTY6MDM6NTYgLTAwMDAKQEAgLTQwMCw3
ICs0MDAsNyBAQCByZWxheV9yZWFkX2h0dHAoc3RydWN0IGJ1ZmZlcmV2ZW50ICpiZXYsCiAJCWlm
IChjcmUtPmxpbmUgIT0gMSkgewogCQkJaWYgKGNyZS0+ZGlyID09IFJFTEFZX0RJUl9SRVFVRVNU
KSB7CiAJCQkJaWYgKHN0cmNhc2VjbXAoIkNvbm5lY3Rpb24iLCBrZXkpID09IDAgJiYKLQkJCQkg
ICAgc3RyY2FzZWNtcCgiVXBncmFkZSIsIHZhbHVlKSA9PSAwKQorCQkJCSAgICBzdHJjYXNlY21w
KCJVcGdyYWRlIiwgdmFsdWUpID49IDApCiAJCQkJCXByaXYtPmh0dHBfdXBncmFkZV9yZXEgfD0K
IAkJCQkJICAgIEhUVFBfQ09OTkVDVElPTl9VUEdSQURFOwogCQkJCWlmIChzdHJjYXNlY21wKCJV
cGdyYWRlIiwga2V5KSA9PSAwICYmCg==




Re: relayd and TLS client cert verification

2018-12-06 Thread Rivo Nurges
Hi!

I have planned to do it myself for quite long time but never got around
doing it. In my testing it works great.

I have patch on top of this which allows to pass remote certificate
and/or parts of it to backend hosts via http headers.

Rivo


On Thu, 2018-12-06 at 05:17 +, Ashe Connor wrote:
> It's been a week or so, so bumping.  (Benno was kind enough to offer
> a
> review but was time-poor recently.)
> 
> Here's a diff for the manpage too.
> 
> Ashe
> 
> 
> Index: usr.sbin/relayd/relayd.conf.5
> ===
> RCS file:
> /home/kivikakk/cvsync/root/src/usr.sbin/relayd/relayd.conf.5,v
> retrieving revision 1.187
> retrieving revision 1.187.6.1
> diff -u -p -r1.187 -r1.187.6.1
> --- usr.sbin/relayd/relayd.conf.5 6 Aug 2018 18:26:29 -   1.187
> +++ usr.sbin/relayd/relayd.conf.5 30 Nov 2018 21:10:06 -  
> 1.187.6.1
> @@ -939,6 +939,10 @@ will be used (strong crypto cipher suite
>  See the CIPHERS section of
>  .Xr openssl 1
>  for information about SSL/TLS cipher suites and preference lists.
> +.It Ic client ca Ar path
> +Require TLS client certificates whose authenticity can be verified
> +against the CA certificate(s) in the specified file in order to
> +proceed beyond the TLS handshake.
>  .It Ic client-renegotiation
>  Allow client-initiated renegotiation.
>  To mitigate a potential DoS risk,
> 



Re: 802.1q with 0 tag

2018-10-12 Thread Rivo Nurges
Hi!

I'll look into the problems(vlan interface with 0 tag and issues
priority differeces) you mentioned. I tested your idea of having vlan
interface without tag and IP on top of physical interface, but IP
traffic doesn't get picked up by parent.

Extreme(Brocade) SLX does it. Depending on the ingress port
configuration packets on egress can be with or without dot1q header.
Seems, it doesn't cause issues with other operating systems.

Rivo

On Fri, 2018-10-12 at 13:38 +1000, David Gwynne wrote:
> Hi Rivo,
> 
> vlan(4) can be configured to receive (and send) packets with 0 as the
> tag on the wire, which this diff will break.
> 
> I'm pretty confident you can leave an IP configured on the physical
> network interface, and create and configure a vlan interface on it
> without setting a VLAN id. The untagged frames should be received as
> normal on the parent, and the tagged frames with the priority will
> come in on the vlan interface but still get accepted for IP on the
> parent.
> 
> Note that the default priority of packets in the OpenBSD kernel is 3,
> which might be higher than what you expect an untagged packets
> priority to be. The default 802.1q priority is 1 iirc.
> 
> I'm curious as to where you see both tagged and untagged frames at
> the same time.
> 
> dlg
> 
> > On 11 Oct 2018, at 7:20 pm, Rivo Nurges 
> > wrote:
> > 
> > Hi!
> > 
> > In theory 802.1q header with vlan tag 0 can be used to just signal
> > priority. Now I'm seeing this in the wild. On a untagged port some
> > packets are coming with dotq header and some without. Currently we
> > drop
> > all the packets with dotq header and vlan tag 0.
> > 
> > Following patch fixes this by recording the priority and removing
> > the
> > header, so existing code to handle the packet. At least NetBSD does
> > something similar.
> > 
> > Rivo
> > 
> > diff --git sys/net/if_ethersubr.c sys/net/if_ethersubr.c
> > index 76f6c3147e0..68f5b03b4f4 100644
> > --- sys/net/if_ethersubr.c
> > +++ sys/net/if_ethersubr.c
> > @@ -362,6 +362,22 @@ ether_input(struct ifnet *ifp, struct mbuf *m,
> > void *cookie)
> > 
> > etype = ntohs(eh->ether_type);
> > 
> > +   /*
> > +* 802.1Q header with a tag of 0 can be used to store priority.
> > +*/
> > +   if (etype == ETHERTYPE_VLAN) {
> > +   struct ether_vlan_header *evl = (void *)eh;
> > +   if (EVL_VLANOFTAG(evl->evl_tag) == EVL_VLID_NULL) {
> > +   etype = ntohs(evl->evl_proto);
> > +   m->m_pkthdr.pf.prio = EVL_PRIOFTAG(evl-
> > >evl_tag);
> > +   /* IEEE 802.1p has prio 0 and 1 swapped */
> > +   if (m->m_pkthdr.pf.prio <= 1)
> > +   m->m_pkthdr.pf.prio = !m-
> > >m_pkthdr.pf.prio;
> > +   memmove((char *)eh + EVL_ENCAPLEN, eh,
> > sizeof(*eh));
> > +   m_adj(m, EVL_ENCAPLEN);
> > +   }
> > +   }
> > +
> > switch (etype) {
> > case ETHERTYPE_IP:
> > input = ipv4_input;
> > 



802.1q with 0 tag

2018-10-11 Thread Rivo Nurges
Hi!

In theory 802.1q header with vlan tag 0 can be used to just signal
priority. Now I'm seeing this in the wild. On a untagged port some
packets are coming with dotq header and some without. Currently we drop
all the packets with dotq header and vlan tag 0.

Following patch fixes this by recording the priority and removing the
header, so existing code to handle the packet. At least NetBSD does
something similar.

Rivo

diff --git sys/net/if_ethersubr.c sys/net/if_ethersubr.c
index 76f6c3147e0..68f5b03b4f4 100644
--- sys/net/if_ethersubr.c
+++ sys/net/if_ethersubr.c
@@ -362,6 +362,22 @@ ether_input(struct ifnet *ifp, struct mbuf *m, void 
*cookie)
 
etype = ntohs(eh->ether_type);
 
+   /*
+* 802.1Q header with a tag of 0 can be used to store priority.
+*/
+   if (etype == ETHERTYPE_VLAN) {
+   struct ether_vlan_header *evl = (void *)eh;
+   if (EVL_VLANOFTAG(evl->evl_tag) == EVL_VLID_NULL) {
+   etype = ntohs(evl->evl_proto);
+   m->m_pkthdr.pf.prio = EVL_PRIOFTAG(evl->evl_tag);
+   /* IEEE 802.1p has prio 0 and 1 swapped */
+   if (m->m_pkthdr.pf.prio <= 1)
+   m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio;
+   memmove((char *)eh + EVL_ENCAPLEN, eh, sizeof(*eh));
+   m_adj(m, EVL_ENCAPLEN);
+   }
+   }
+
switch (etype) {
case ETHERTYPE_IP:
input = ipv4_input;



Re: install.sub - disklabel template modification

2018-08-30 Thread Rivo Nurges
Hi!

"URL to autopartitioning template for disklabel =
file:///disklabel.auto" works fine.

Rivo

On Thu, 2018-08-30 at 13:27 +, Jiri B. wrote:
> Hi,
> 
> if somebody would put into install.conf following line:
> 
>   URL to autopartitioning template for disklabel =
> /disklabel.template
> 
> ftp would end in its prompt.
> 
> # ftp -Vo -
> /disklabel.template  
>  
> ftp: /disklabel.template: no address associated with name
> ftp> 
> 
> I took current check for ramdisk local {install,upgrade}.conf
> 
>   649:[[ -f $_rf ]] && _rf="file://$_rf"
> 
> and added it to disklabel_autolayout(), so installer would know
> how to handle path to ramdisk's local disklabel template without
> file:// uri.
> 
> Jiri
> 
> ---%>---
> diff --git distrib/miniroot/install.sub distrib/miniroot/install.sub
> index 740064a86a8..63ecf5cab14 100644
> --- distrib/miniroot/install.sub
> +++ distrib/miniroot/install.sub
> @@ -414,6 +414,7 @@ disklabel_autolayout() {
> err_exit "https not supported on this
> platform."
> fi
> echo "Fetching $resp"
> + [[ -f $resp ]] && resp="file://$resp"
> if unpriv ftp -Vo - "$resp" >$_dl && [[ -s $_dl ]];
> then
> disklabel -T $_dl -F $_f -w -A $_disk &&
> return
> err_exit "Autopartitioning failed."
> ---%<---
> 



Re: relayd http check fix

2018-04-06 Thread Rivo Nurges
Hi!

ping

Rivo

On Wed, 2018-03-28 at 16:56 +, Rivo Nurges wrote:
> Hi!
> 
> If relayd http check doesn't get any answer to its http check it
> marks
> backend host as up.
> 
> host x.y.z, check http code (2010ms,tcp read timeout), state down ->
> up, availability 14.29%
> 
> sample config:
> relay test {
>   listen on x.x.x.x port 
>   forward to  port  check http "/" code 200
> }
> 
> sample server:
> while :;do nc -l ;done
> 
> fix:
> Index: usr.sbin/relayd/check_tcp.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/check_tcp.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 check_tcp.c
> --- usr.sbin/relayd/check_tcp.c   4 Jul 2017 20:27:09 -   
> 1.55
> +++ usr.sbin/relayd/check_tcp.c   28 Mar 2018 16:45:38 -
> @@ -243,8 +243,10 @@ tcp_read_buf(int s, short event, void *a
>   if (event == EV_TIMEOUT) {
>   if (ibuf_size(cte->buf))
>   (void)cte->validate_close(cte);
> - else
> + else {
>   cte->host->he = HCE_TCP_READ_TIMEOUT;
> + cte->host->up = HOST_DOWN;
> + }   
>   tcp_close(cte, cte->host->up == HOST_UP ? 0 :
> HOST_DOWN);
>   hce_notify_done(cte->host, cte->host->he);
>   return;
> 



relayd http check fix

2018-03-28 Thread Rivo Nurges
Hi!

If relayd http check doesn't get any answer to its http check it marks
backend host as up.

host x.y.z, check http code (2010ms,tcp read timeout), state down ->
up, availability 14.29%

sample config:
relay test {
  listen on x.x.x.x port 
  forward to  port  check http "/" code 200
}

sample server:
while :;do nc -l ;done

fix:
Index: usr.sbin/relayd/check_tcp.c
===
RCS file: /cvs/src/usr.sbin/relayd/check_tcp.c,v
retrieving revision 1.55
diff -u -p -r1.55 check_tcp.c
--- usr.sbin/relayd/check_tcp.c 4 Jul 2017 20:27:09 -   1.55
+++ usr.sbin/relayd/check_tcp.c 28 Mar 2018 16:45:38 -
@@ -243,8 +243,10 @@ tcp_read_buf(int s, short event, void *a
if (event == EV_TIMEOUT) {
if (ibuf_size(cte->buf))
(void)cte->validate_close(cte);
-   else
+   else {
cte->host->he = HCE_TCP_READ_TIMEOUT;
+   cte->host->up = HOST_DOWN;
+   }   
tcp_close(cte, cte->host->up == HOST_UP ? 0 : HOST_DOWN);
hce_notify_done(cte->host, cte->host->he);
return;



Re: relayd and PUT

2018-01-19 Thread Rivo Nurges
Hi!

On Fri, 2018-01-05 at 00:12 +0100, Alexander Bluhm wrote:
> I have commited more regression tests that check the timeout with
> unidirectional traffic flow.  I could not find an error.  In theory
> when we have an idle timeout in one direction, relayd checks wheter
> there is trafic flowing in the other direction.  The tests set the
> timeout to 2 seconds and send 5 bytes while sleeping one second
> between each byte.  The timeout does not trigger.
> So it seems that you encounter some corner case.  I need more
> information.

Yes, its a bit harder to trigger. First, currently relayd opens server
connection only after first client request finishes. If the first
request is long PUT relayd buffers the PUT and the problem doesn't
appear. But it triggers another problem, depending on the request size
you run out of memory. I have another patch for this. It opens the
relay>server socket earlyer and makes the timeout problem even easyer
to trigger. I will send it separately.

So to get the server connection opened and the timeout to happen you
need to do some small GET(or whatever) request and keep the connection
open. In my test case I use "GET /; PUT /largefile"

> - Do you use http or https?

both have the problem

> - Do you use persistent connections?

yes

> - Do you use chunked encoding?

no

> - Does it only occur with http or also with plain tcp?

only http

> - Does disabling socket splicing help?

the problem happens when libevent code is in use
either splicing is disabled or not available(https)

> - Does it happen when the connect to the server is slow?
> 
> While testing I saw that with socket splicing the timeout is handled
> twice.  We get an wakeup from the idle splicing and from libevent
> timeout.  I think it is sufficient to only use the idle splicing
> if it is available.

I noticed it too, but it doesn't seem to make things worse.

> Does this diff help?

This diff doesn't change things.

Rivo

Re: relayd and PUT

2018-01-19 Thread Rivo Nurges
Hi!

Please ingore this.

Rivo

On Fri, 2018-01-19 at 14:01 +, Rivo Nurges wrote:
> On Fri, 2018-01-05 at 00:12 +0100, Alexander Bluhm wrote:
> > On Wed, Dec 13, 2017 at 07:42:03AM +0100, Claudio Jeker wrote:
> > > On Wed, Dec 13, 2017 at 12:25:39AM +, Rivo Nurges wrote:
> > > > If you http PUT a "big" file through relayd, server<>relay read
> > > > side
> > > > will eventually get a EVBUFFER_TIMEOUT. Nothing comes back from
> > > > the
> > > > server until the PUT is done. I disabled server read timeouts
> > > > for
> > > > PUT
> > > > requests.
> > > 
> > > I have seen something similar and came to the conclusion that the
> > > timeout
> > > handling of relayd is not correct. As long as traffic is flowing
> > > the
> > > timeout should be reset (at least that is what every other
> > > implementation
> > > does). This is not really happening in relayd. I have seen this
> > > on
> > > GET
> > > requests that are huge (timeout hits in the middle of the
> > > transimit
> > > and
> > > kills the session).
> > 
> > I have commited more regression tests that check the timeout with
> > unidirectional traffic flow.  I could not find an error.  In theory
> > when we have an idle timeout in one direction, relayd checks wheter
> > there is trafic flowing in the other direction.  The tests set the
> > timeout to 2 seconds and send 5 bytes while sleeping one second
> > between each byte.  The timeout does not trigger.
> > 
> > So it seems that you encounter some corner case.  I need more
> > information.
> > 
> > - Do you use http or https?
> > - Do you use persistent connections?
> > - Do you use chunked encoding?
> > - Does it only occur with http or also with plain tcp?
> > - Does disabling socket splicing help?
> > - Does it happen when the connect to the server is slow?
> > 
> > While testing I saw that with socket splicing the timeout is
> > handled
> > twice.  We get an wakeup from the idle splicing and from libevent
> > timeout.  I think it is sufficient to only use the idle splicing
> > if it is available.
> > 
> > Does this diff help?
> > 
> > bluhm
> > 
> > Index: relay.c
> > ===
> > RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relay.c,v
> > retrieving revision 1.237
> > diff -u -p -r1.237 relay.c
> > --- relay.c 27 Dec 2017 15:53:30 -  1.237
> > +++ relay.c 4 Jan 2018 22:44:20 -
> > @@ -733,16 +733,21 @@ relay_connected(int fd, short sig, void 
> > if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls !=
> > NULL))
> > relay_tls_connected(out);
> >  
> > -   bufferevent_settimeout(bev,
> > -   rlay->rl_conf.timeout.tv_sec, rlay-
> > > rl_conf.timeout.tv_sec);
> > 
> > bufferevent_setwatermark(bev, EV_WRITE,
> > RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
> > bufferevent_enable(bev, EV_READ|EV_WRITE);
> > if (con->se_in.bev)
> > bufferevent_enable(con->se_in.bev, EV_READ);
> >  
> > -   if (relay_splice(>se_out) == -1)
> > +   switch (relay_splice(>se_out)) {
> > +   case 0:
> > +   bufferevent_settimeout(bev,
> > +   rlay->rl_conf.timeout.tv_sec, rlay-
> > > rl_conf.timeout.tv_sec);
> > 
> > +   break;
> > +   case -1:
> > relay_close(con, strerror(errno));
> > +   break;
> > +   }
> >  }
> >  
> >  void
> > @@ -784,14 +789,19 @@ relay_input(struct rsession *con)
> > if ((rlay->rl_conf.flags & F_TLS) && con->se_in.tls !=
> > NULL)
> > relay_tls_connected(>se_in);
> >  
> > -   bufferevent_settimeout(con->se_in.bev,
> > -   rlay->rl_conf.timeout.tv_sec, rlay-
> > > rl_conf.timeout.tv_sec);
> > 
> > bufferevent_setwatermark(con->se_in.bev, EV_WRITE,
> > RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
> > bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE);
> >  
> > -   if (relay_splice(>se_in) == -1)
> > +   switch (relay_splice(>se_in)) {
> > +   case 0:
> > +   bufferevent_settimeout(con->se_in.bev,
> > +   rlay->rl_conf.timeout.tv_sec, rlay-
> > > rl_conf.timeout.tv_sec);
> > 
> > +   break;
> > +   case -1:
> > relay_close(con, strerror(errno));
> > +   break;
> > +   }
> >  }
> >  
> >  void

Re: relayd and PUT

2018-01-19 Thread Rivo Nurges
On Fri, 2018-01-05 at 00:12 +0100, Alexander Bluhm wrote:
> On Wed, Dec 13, 2017 at 07:42:03AM +0100, Claudio Jeker wrote:
> > On Wed, Dec 13, 2017 at 12:25:39AM +0000, Rivo Nurges wrote:
> > > If you http PUT a "big" file through relayd, server<>relay read
> > > side
> > > will eventually get a EVBUFFER_TIMEOUT. Nothing comes back from
> > > the
> > > server until the PUT is done. I disabled server read timeouts for
> > > PUT
> > > requests.
> > 
> > I have seen something similar and came to the conclusion that the
> > timeout
> > handling of relayd is not correct. As long as traffic is flowing
> > the
> > timeout should be reset (at least that is what every other
> > implementation
> > does). This is not really happening in relayd. I have seen this on
> > GET
> > requests that are huge (timeout hits in the middle of the transimit
> > and
> > kills the session).
> 
> I have commited more regression tests that check the timeout with
> unidirectional traffic flow.  I could not find an error.  In theory
> when we have an idle timeout in one direction, relayd checks wheter
> there is trafic flowing in the other direction.  The tests set the
> timeout to 2 seconds and send 5 bytes while sleeping one second
> between each byte.  The timeout does not trigger.
> 
> So it seems that you encounter some corner case.  I need more
> information.
> 
> - Do you use http or https?
> - Do you use persistent connections?
> - Do you use chunked encoding?
> - Does it only occur with http or also with plain tcp?
> - Does disabling socket splicing help?
> - Does it happen when the connect to the server is slow?
> 
> While testing I saw that with socket splicing the timeout is handled
> twice.  We get an wakeup from the idle splicing and from libevent
> timeout.  I think it is sufficient to only use the idle splicing
> if it is available.
> 
> Does this diff help?
> 
> bluhm
> 
> Index: relay.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.237
> diff -u -p -r1.237 relay.c
> --- relay.c   27 Dec 2017 15:53:30 -  1.237
> +++ relay.c   4 Jan 2018 22:44:20 -
> @@ -733,16 +733,21 @@ relay_connected(int fd, short sig, void 
>   if ((rlay->rl_conf.flags & F_TLSCLIENT) && (out->tls !=
> NULL))
>   relay_tls_connected(out);
>  
> - bufferevent_settimeout(bev,
> - rlay->rl_conf.timeout.tv_sec, rlay-
> >rl_conf.timeout.tv_sec);
>   bufferevent_setwatermark(bev, EV_WRITE,
>   RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
>   bufferevent_enable(bev, EV_READ|EV_WRITE);
>   if (con->se_in.bev)
>   bufferevent_enable(con->se_in.bev, EV_READ);
>  
> - if (relay_splice(>se_out) == -1)
> + switch (relay_splice(>se_out)) {
> + case 0:
> + bufferevent_settimeout(bev,
> + rlay->rl_conf.timeout.tv_sec, rlay-
> >rl_conf.timeout.tv_sec);
> + break;
> + case -1:
>   relay_close(con, strerror(errno));
> + break;
> + }
>  }
>  
>  void
> @@ -784,14 +789,19 @@ relay_input(struct rsession *con)
>   if ((rlay->rl_conf.flags & F_TLS) && con->se_in.tls != NULL)
>   relay_tls_connected(>se_in);
>  
> - bufferevent_settimeout(con->se_in.bev,
> - rlay->rl_conf.timeout.tv_sec, rlay-
> >rl_conf.timeout.tv_sec);
>   bufferevent_setwatermark(con->se_in.bev, EV_WRITE,
>   RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
>   bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE);
>  
> - if (relay_splice(>se_in) == -1)
> + switch (relay_splice(>se_in)) {
> + case 0:
> + bufferevent_settimeout(con->se_in.bev,
> + rlay->rl_conf.timeout.tv_sec, rlay-
> >rl_conf.timeout.tv_sec);
> + break;
> + case -1:
>   relay_close(con, strerror(errno));
> + break;
> + }
>  }
>  
>  void

relayd timeout handling

2017-12-28 Thread Rivo Nurges
Hi!

I'm resending my previous proposal.

Bump client<>relay, relay<>server bufferevent timeouts as long there is
some traffic flowing. Current code doesn't handle long unidirectional
flows correctly.

Simplest route would be to check presence of traffic every second, but
I choose to schedule the task at half of the remainig timeout.


Rivo

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.236
diff -u -p -r1.236 relay.c
--- usr.sbin/relayd/relay.c 28 Nov 2017 01:51:47 -  1.236
+++ usr.sbin/relayd/relay.c 28 Dec 2017 16:28:03 -
@@ -69,6 +69,7 @@ intrelay_socket_connect(struct sockad
 
 voidrelay_accept(int, short, void *);
 voidrelay_input(struct rsession *);
+voidrelay_timeout(int, short, void *);
 
 voidrelay_hash_addr(SIPHASH_CTX *, struct sockaddr_storage *, int);
 
@@ -662,6 +663,7 @@ relay_connected(int fd, short sig, void 
struct bufferevent  *bev;
struct ctl_relay_event  *out = >se_out;
socklen_tlen;
+   struct timeval   tv;
int  error;
 
if (sig == EV_TIMEOUT) {
@@ -724,6 +726,14 @@ relay_connected(int fd, short sig, void 
 
bufferevent_settimeout(bev,
rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
+
+   evtimer_set(>se_ev, relay_timeout, con);
+   timerclear();
+   tv.tv_sec = rlay->rl_conf.timeout.tv_sec / 2;
+   if (tv.tv_sec == 0)
+   tv.tv_usec = 50;
+   evtimer_add(>se_ev, );
+
bufferevent_setwatermark(bev, EV_WRITE,
RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
bufferevent_enable(bev, EV_READ|EV_WRITE);
@@ -955,6 +965,37 @@ relay_spliceadjust(struct ctl_relay_even
cre->splicelen = -1;
 
return (0);
+}
+
+void
+relay_timeout(int fd, short event, void *arg)
+{
+   struct rsession *con = arg;
+   struct relay*rlay = con->se_relay;
+   struct timeval   tv, tv_now;
+   time_t   timeout;
+
+   timerclear();
+   getmonotime(_now);
+   timersub(_now, >se_tv_last, );
+   timeout = rlay->rl_conf.timeout.tv_sec - tv.tv_sec;
+
+   DPRINTF("%s: session %d: last %llds ago, timeout %llds", __func__,
+   con->se_id, tv.tv_sec, timeout);
+
+   if (timeout > 0){
+   bufferevent_settimeout(con->se_out.bev, timeout, timeout);
+   bufferevent_settimeout(con->se_in.bev, timeout, timeout);
+   }
+
+   evtimer_set(>se_ev, relay_timeout, con);
+   tv.tv_sec = (rlay->rl_conf.timeout.tv_sec - tv.tv_sec) / 2;
+   if (tv.tv_sec == 0)
+   tv.tv_usec = 50;
+   evtimer_add(>se_ev, );
+
+   DPRINTF("%s: session %d: next after %llds", __func__, con->se_id,
+   tv.tv_sec);
 }
 
 void

Re: relayd and PUT

2017-12-15 Thread Rivo Nurges
Hi!

On Wed, 2017-12-13 at 07:42 +0100, Claudio Jeker wrote:
> I have seen something similar and came to the conclusion that the
> timeout
> handling of relayd is not correct. As long as traffic is flowing the
> timeout should be reset (at least that is what every other
> implementation
> does). This is not really happening in relayd. I have seen this on
> GET
> requests that are huge (timeout hits in the middle of the transimit
> and
> kills the session).
> 
> Because of this I think the diff is a workaround and does not solve
> the
> real underlying problem.

My next try. It schedules a timer event to bump bufferevent timeouts.
One of the possibilities is to schedule it eg once every second, but I
choose to schedule the event at half of the remaining bufferevent
timeout.

Rivo

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.236
diff -u -p -r1.236 relay.c
--- usr.sbin/relayd/relay.c 28 Nov 2017 01:51:47 -  1.236
+++ usr.sbin/relayd/relay.c 16 Dec 2017 00:36:31 -
@@ -69,6 +69,7 @@ intrelay_socket_connect(struct sockad
 
 voidrelay_accept(int, short, void *);
 voidrelay_input(struct rsession *);
+voidrelay_timeout(int, short, void *);
 
 voidrelay_hash_addr(SIPHASH_CTX *, struct sockaddr_storage *, int);
 
@@ -662,6 +663,7 @@ relay_connected(int fd, short sig, void 
struct bufferevent  *bev;
struct ctl_relay_event  *out = >se_out;
socklen_tlen;
+   struct timeval   tv;
int  error;
 
if (sig == EV_TIMEOUT) {
@@ -724,6 +726,14 @@ relay_connected(int fd, short sig, void 
 
bufferevent_settimeout(bev,
rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
+
+   evtimer_set(>se_ev, relay_timeout, con);
+   timerclear();
+   tv.tv_sec = rlay->rl_conf.timeout.tv_sec / 2;
+   if (tv.tv_sec == 0)
+   tv.tv_usec = 50;
+   evtimer_add(>se_ev, );
+
bufferevent_setwatermark(bev, EV_WRITE,
RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
bufferevent_enable(bev, EV_READ|EV_WRITE);
@@ -955,6 +965,38 @@ relay_spliceadjust(struct ctl_relay_even
cre->splicelen = -1;
 
return (0);
+}
+
+void
+relay_timeout(int fd, short event, void *arg)
+{
+   struct rsession *con = arg;
+   struct ctl_relay_event  *cre = >se_out;
+   struct relay*rlay = con->se_relay;
+   struct timeval   tv, tv_now;
+   time_t   timeout;
+
+   timerclear();
+   getmonotime(_now);
+   timersub(_now, >se_tv_last, );
+   timeout = rlay->rl_conf.timeout.tv_sec - tv.tv_sec;
+
+   DPRINTF("%s: session %d: last %llds ago, timeout %llds", __func__,
+   con->se_id, tv.tv_sec, timeout);
+
+   if (timeout > 0){
+   bufferevent_settimeout(cre->bev, timeout, timeout);
+   bufferevent_settimeout(con->se_in.bev, timeout, timeout);
+   }
+
+   evtimer_set(>se_ev, relay_timeout, con);
+   tv.tv_sec = (rlay->rl_conf.timeout.tv_sec - tv.tv_sec) / 2;
+   if (tv.tv_sec == 0)
+   tv.tv_usec = 50;
+   evtimer_add(>se_ev, );
+
+   DPRINTF("%s: session %d: next after %llds", __func__, con->se_id,
+   tv.tv_sec);
 }
 
 void

Re: relayd and PUT

2017-12-13 Thread Rivo Nurges
Hi!

Thanks for enlightening me, I’ll try to fix the real problem.

Rivo

> On 13 Dec 2017, at 08:42, Claudio Jeker <cje...@diehard.n-r-g.com> wrote:
> 
>> On Wed, Dec 13, 2017 at 12:25:39AM +, Rivo Nurges wrote:
>> Hi!
>> 
>> If you http PUT a "big" file through relayd, server<>relay read side
>> will eventually get a EVBUFFER_TIMEOUT. Nothing comes back from the
>> server until the PUT is done. I disabled server read timeouts for PUT
>> requests.
>> 
>> While trying to fix the issue I managed to trigger another problem. For
>> HTTP relays we open relay<>server connection only after the first
>> request is completely read from the client. If http PUT is the the
>> first request and is big enough we will run out of memory and
>> eventually out of swap. To avoid the issue I will open relay<>server
>> connection earlyer and let relayd to start sending the stuff to the
>> server.
>> 
>> And another one I don't know how to fix. If relayd fills all memory and
>> swap with buffers kernel enters infinite loop. relayd is in flt_noram
>> state and pagedaemon constantly tries to free something without any
>> luck. userland scheduling halts. bgp looses its peers but carp still
>> happily sends its hellos...
>> 
> 
> I have seen something similar and came to the conclusion that the timeout
> handling of relayd is not correct. As long as traffic is flowing the
> timeout should be reset (at least that is what every other implementation
> does). This is not really happening in relayd. I have seen this on GET
> requests that are huge (timeout hits in the middle of the transimit and
> kills the session).
> 
> Because of this I think the diff is a workaround and does not solve the
> real underlying problem.
> 
>> Rivo
>> 
>> Index: usr.sbin/relayd/relay.c
>> ===
>> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
>> retrieving revision 1.236
>> diff -u -p -r1.236 relay.c
>> --- usr.sbin/relayd/relay.c28 Nov 2017 01:51:47 -1.
>> 236
>> +++ usr.sbin/relayd/relay.c13 Dec 2017 00:05:33 -
>> @@ -723,7 +723,8 @@ relay_connected(int fd, short sig, void 
>>relay_tls_connected(out);
>> 
>>bufferevent_settimeout(bev,
>> -rlay->rl_conf.timeout.tv_sec, rlay-
>>> rl_conf.timeout.tv_sec);
>> +con->se_out.writeonly ? 0 : rlay->rl_conf.timeout.tv_sec,
>> +rlay->rl_conf.timeout.tv_sec);
>>bufferevent_setwatermark(bev, EV_WRITE,
>>RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
>>bufferevent_enable(bev, EV_READ|EV_WRITE);
>> Index: usr.sbin/relayd/relay_http.c
>> ===
>> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
>> retrieving revision 1.70
>> diff -u -p -r1.70 relay_http.c
>> --- usr.sbin/relayd/relay_http.c27 Nov 2017 16:25:50 -
>> 1.70
>> +++ usr.sbin/relayd/relay_http.c13 Dec 2017 00:05:33 -
>> @@ -439,6 +439,10 @@ relay_read_http(struct bufferevent *bev,
>>case HTTP_METHOD_OPTIONS:
>>case HTTP_METHOD_POST:
>>case HTTP_METHOD_PUT:
>> +con->se_out.writeonly = 1;
>> +if(cre->dst->state == STATE_CONNECTED)
>> +bufferevent_settimeout(bev,
>> +0, rlay->rl_conf.timeout.tv_sec); 
>>case HTTP_METHOD_RESPONSE:
>>/* WebDAV methods */
>>case HTTP_METHOD_PROPFIND:
>> @@ -569,6 +573,9 @@ relay_read_httpcontent(struct buffereven
>>goto fail;
>>cre->toread -= size;
>>}
>> +if (cre->dst->writeonly && cre->dst->state !=
>> STATE_CONNECTED)
>> +if (relay_connect(con) == -1)
>> +goto fail;
>>DPRINTF("%s: done, size %lu, to read %lld", __func__,
>>size, cre->toread);
>>}
>> Index: usr.sbin/relayd/relayd.h
>> ===
>> RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
>> retrieving revision 1.248
>> diff -u -p -r1.248 relayd.h
>> --- usr.sbin/relayd/relayd.h28 Nov 2017 18:25:53 -1
>> .248
>> +++ usr.sbin/relayd/relayd.h13 Dec 2017 00:05:33 -
>> @@ -218,6 +218,7 @@ struct ctl_relay_event {
>>int line;
>>int done;
>>int timedout;
>> +int writeonly;
>>enum relay_state state;
>>enum direction dir;
>> 
> 
> -- 
> :wq Claudio
> 


Re: relayd and PUT

2017-12-12 Thread Rivo Nurges
Hi!

Without text mangling this time...

Rivo

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.236
diff -u -p -r1.236 relay.c
--- usr.sbin/relayd/relay.c 28 Nov 2017 01:51:47 -  1.236
+++ usr.sbin/relayd/relay.c 13 Dec 2017 00:05:33 -
@@ -723,7 +723,8 @@ relay_connected(int fd, short sig, void 
relay_tls_connected(out);
 
bufferevent_settimeout(bev,
-   rlay->rl_conf.timeout.tv_sec, rlay->rl_conf.timeout.tv_sec);
+   con->se_out.writeonly ? 0 : rlay->rl_conf.timeout.tv_sec,
+   rlay->rl_conf.timeout.tv_sec);
bufferevent_setwatermark(bev, EV_WRITE,
RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
bufferevent_enable(bev, EV_READ|EV_WRITE);
Index: usr.sbin/relayd/relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.70
diff -u -p -r1.70 relay_http.c
--- usr.sbin/relayd/relay_http.c27 Nov 2017 16:25:50 -  1.70
+++ usr.sbin/relayd/relay_http.c13 Dec 2017 00:05:33 -
@@ -439,6 +439,10 @@ relay_read_http(struct bufferevent *bev,
case HTTP_METHOD_OPTIONS:
case HTTP_METHOD_POST:
case HTTP_METHOD_PUT:
+   con->se_out.writeonly = 1;
+   if(cre->dst->state == STATE_CONNECTED)
+   bufferevent_settimeout(bev,
+   0, rlay->rl_conf.timeout.tv_sec); 
case HTTP_METHOD_RESPONSE:
/* WebDAV methods */
case HTTP_METHOD_PROPFIND:
@@ -569,6 +573,9 @@ relay_read_httpcontent(struct buffereven
goto fail;
cre->toread -= size;
}
+   if (cre->dst->writeonly && cre->dst->state != STATE_CONNECTED)
+   if (relay_connect(con) == -1)
+   goto fail;
DPRINTF("%s: done, size %lu, to read %lld", __func__,
size, cre->toread);
}
Index: usr.sbin/relayd/relayd.h
===
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.248
diff -u -p -r1.248 relayd.h
--- usr.sbin/relayd/relayd.h28 Nov 2017 18:25:53 -  1.248
+++ usr.sbin/relayd/relayd.h13 Dec 2017 00:05:33 -
@@ -218,6 +218,7 @@ struct ctl_relay_event {
int  line;
int  done;
int  timedout;
+   int  writeonly;
enum relay_state state;
enum direction   dir;
 


begin-base64 644 relayd_put.diff
SW5kZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheS5jCj09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KUkNTIGZpbGU6IC9jdnMv
c3JjL3Vzci5zYmluL3JlbGF5ZC9yZWxheS5jLHYKcmV0cmlldmluZyByZXZpc2lvbiAxLjIzNgpk
aWZmIC11IC1wIC1yMS4yMzYgcmVsYXkuYwotLS0gdXNyLnNiaW4vcmVsYXlkL3JlbGF5LmMJMjgg
Tm92IDIwMTcgMDE6NTE6NDcgLTAwMDAJMS4yMzYKKysrIHVzci5zYmluL3JlbGF5ZC9yZWxheS5j
CTEzIERlYyAyMDE3IDAwOjA1OjMzIC0wMDAwCkBAIC03MjMsNyArNzIzLDggQEAgcmVsYXlfY29u
bmVjdGVkKGludCBmZCwgc2hvcnQgc2lnLCB2b2lkIAogCQlyZWxheV90bHNfY29ubmVjdGVkKG91
dCk7CiAKIAlidWZmZXJldmVudF9zZXR0aW1lb3V0KGJldiwKLQkgICAgcmxheS0+cmxfY29uZi50
aW1lb3V0LnR2X3NlYywgcmxheS0+cmxfY29uZi50aW1lb3V0LnR2X3NlYyk7CisJICAgIGNvbi0+
c2Vfb3V0LndyaXRlb25seSA/IDAgOiBybGF5LT5ybF9jb25mLnRpbWVvdXQudHZfc2VjLAorCSAg
ICBybGF5LT5ybF9jb25mLnRpbWVvdXQudHZfc2VjKTsKIAlidWZmZXJldmVudF9zZXR3YXRlcm1h
cmsoYmV2LCBFVl9XUklURSwKIAkJUkVMQVlfTUlOX1BSRUZFVENIRUQgKiBwcm90by0+dGNwYnVm
c2l6LCAwKTsKIAlidWZmZXJldmVudF9lbmFibGUoYmV2LCBFVl9SRUFEfEVWX1dSSVRFKTsKSW5k
ZXg6IHVzci5zYmluL3JlbGF5ZC9yZWxheV9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTogL2N2
cy9zcmMvdXNyLnNiaW4vcmVsYXlkL3JlbGF5X2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNpb24g
MS43MApkaWZmIC11IC1wIC1yMS43MCByZWxheV9odHRwLmMKLS0tIHVzci5zYmluL3JlbGF5ZC9y
ZWxheV9odHRwLmMJMjcgTm92IDIwMTcgMTY6MjU6NTAgLTAwMDAJMS43MAorKysgdXNyLnNiaW4v
cmVsYXlkL3JlbGF5X2h0dHAuYwkxMyBEZWMgMjAxNyAwMDowNTozMyAtMDAwMApAQCAtNDM5LDYg
KzQzOSwxMCBAQCByZWxheV9yZWFkX2h0dHAoc3RydWN0IGJ1ZmZlcmV2ZW50ICpiZXYsCiAJCWNh
c2UgSFRUUF9NRVRIT0RfT1BUSU9OUzoKIAkJY2FzZSBIVFRQX01FVEhPRF9QT1NUOgogCQljYXNl
IEhUVFBfTUVUSE9EX1BVVDoKKwkJCWNvbi0+c2Vfb3V0LndyaXRlb25seSA9IDE7CisJCQlpZihj
cmUtPmRzdC0+c3RhdGUgPT0gU1RBVEVfQ09OTkVDVEVEKQorCQkJCWJ1ZmZlcmV2ZW50X3NldHRp
bWVvdXQoYmV2LAorCQkJCSAgICAwLCBybGF5LT5ybF9jb25mLnRpbWVvdXQudHZfc2VjKTsgCiAJ
CWNhc2UgSFRUUF9NRVRIT0RfUkVTUE9OU0U6CiAJCS8qIFdlYkRBViBtZXRob2RzICovCiAJCWNh
c2UgSFRUUF9NRVRIT0RfUFJPUEZJTkQ6CkBAIC01NjksNiArNTczLDkgQEAgcmVsYXlfcmVhZF9o
dHRwY29udGVudChzdHJ1Y3QgYnVmZmVyZXZlbgogCQkJCWdvdG8gZmFpbDsKIAkJCWNyZS0+dG9y

relayd and PUT

2017-12-12 Thread Rivo Nurges
Hi!

If you http PUT a "big" file through relayd, server<>relay read side
will eventually get a EVBUFFER_TIMEOUT. Nothing comes back from the
server until the PUT is done. I disabled server read timeouts for PUT
requests.

While trying to fix the issue I managed to trigger another problem. For
HTTP relays we open relay<>server connection only after the first
request is completely read from the client. If http PUT is the the
first request and is big enough we will run out of memory and
eventually out of swap. To avoid the issue I will open relay<>server
connection earlyer and let relayd to start sending the stuff to the
server.

And another one I don't know how to fix. If relayd fills all memory and
swap with buffers kernel enters infinite loop. relayd is in flt_noram
state and pagedaemon constantly tries to free something without any
luck. userland scheduling halts. bgp looses its peers but carp still
happily sends its hellos...

Rivo

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.236
diff -u -p -r1.236 relay.c
--- usr.sbin/relayd/relay.c 28 Nov 2017 01:51:47 -  1.
236
+++ usr.sbin/relayd/relay.c 13 Dec 2017 00:05:33 -
@@ -723,7 +723,8 @@ relay_connected(int fd, short sig, void 
relay_tls_connected(out);
 
bufferevent_settimeout(bev,
-   rlay->rl_conf.timeout.tv_sec, rlay-
>rl_conf.timeout.tv_sec);
+   con->se_out.writeonly ? 0 : rlay->rl_conf.timeout.tv_sec,
+   rlay->rl_conf.timeout.tv_sec);
bufferevent_setwatermark(bev, EV_WRITE,
RELAY_MIN_PREFETCHED * proto->tcpbufsiz, 0);
bufferevent_enable(bev, EV_READ|EV_WRITE);
Index: usr.sbin/relayd/relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.70
diff -u -p -r1.70 relay_http.c
--- usr.sbin/relayd/relay_http.c27 Nov 2017 16:25:50 -  
1.70
+++ usr.sbin/relayd/relay_http.c13 Dec 2017 00:05:33 -
@@ -439,6 +439,10 @@ relay_read_http(struct bufferevent *bev,
case HTTP_METHOD_OPTIONS:
case HTTP_METHOD_POST:
case HTTP_METHOD_PUT:
+   con->se_out.writeonly = 1;
+   if(cre->dst->state == STATE_CONNECTED)
+   bufferevent_settimeout(bev,
+   0, rlay->rl_conf.timeout.tv_sec); 
case HTTP_METHOD_RESPONSE:
/* WebDAV methods */
case HTTP_METHOD_PROPFIND:
@@ -569,6 +573,9 @@ relay_read_httpcontent(struct buffereven
goto fail;
cre->toread -= size;
}
+   if (cre->dst->writeonly && cre->dst->state !=
STATE_CONNECTED)
+   if (relay_connect(con) == -1)
+   goto fail;
DPRINTF("%s: done, size %lu, to read %lld", __func__,
size, cre->toread);
}
Index: usr.sbin/relayd/relayd.h
===
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.248
diff -u -p -r1.248 relayd.h
--- usr.sbin/relayd/relayd.h28 Nov 2017 18:25:53 -  1
.248
+++ usr.sbin/relayd/relayd.h13 Dec 2017 00:05:33 -
@@ -218,6 +218,7 @@ struct ctl_relay_event {
int  line;
int  done;
int  timedout;
+   int  writeonly;
enum relay_state state;
enum direction   dir;
 

Re: relayd status code handling

2017-11-17 Thread Rivo Nurges
Hi!

I have 4 digit number of relayd instances and I'v seen plenty of such
products. ownCloud, Nextcloud and some Atlassian products to name few.
relayd seems to be the only one to enforce the RFC so strictly. I'd be
glad if this gets relaxed a bit.

Rivo

On Fri, 2017-11-17 at 18:52 +0100, Sebastian Benoit wrote:
> Hi,
> 
> relayd enforces a rule in rfc section 3.3.2:
> 
> rfc 7230 3.3 Message Body
> 
>All 1xx (Informational), 204 (No Content), and 304 (Not Modified)
>responses do not include a message body.  All other responses do
>include a message body, although the body might be of zero length.
> 
> rfc 7230 3.3.2.  Content-Length
> 
>A server MUST NOT send a Content-Length header field in any
> response
>with a status code of 1xx (Informational) or 204 (No Content).  A
>server MUST NOT send a Content-Length header field in any 2xx
>(Successful) response to a CONNECT request (Section 4.3.6 of
>[RFC7231]).
> 
> 
> There is also this paragraph in Section 3.3.3 thats relevant:
> 
> 
>4.  If a message is received without Transfer-Encoding and with
>either multiple Content-Length header fields having differing
>field-values or a single Content-Length header field having an
>invalid value, then the message framing is invalid and the
>recipient MUST treat it as an unrecoverable error.  If this is
> a
>request message, the server MUST respond with a 400 (Bad
> Request)
>status code and then close the connection.  If this is a
> response
>message received by a proxy, the proxy MUST close the
> connection
>to the server, discard the received response, and send a 502
> (Bad
>Gateway) response to the client.  If this is a response
> message
>received by a user agent, the user agent MUST close the
>connection to the server and discard the received response.
> 
> 
> There are two problems with this:
> 
> * I have found a Tomcat Server that sends "204 No Content" with a
>   "Content-Length: 0" Header.
> 
> * Relayd sends the wrong HTTP Status Code, it should be 502 Bad
> Gateway
> 
> Here is a diff that relaxes the logic: send a 502 Bad Gateway, but
> only if Content-Length != 0.
> 
> ok?
> 
> diff --git usr.sbin/relayd/relay_http.c usr.sbin/relayd/relay_http.c
> index 3b6f8e84e37..ad45cf2d5d6 100644
> --- usr.sbin/relayd/relay_http.c
> +++ usr.sbin/relayd/relay_http.c
> @@ -324,19 +324,6 @@ relay_read_http(struct bufferevent *bev, void
> *arg)
>   relay_abort_http(con, 400,
> "malformed", 0);
>   goto abort;
>   }
> - /*
> -  * response with a status code of 1xx
> -  * (Informational) or 204 (No Content) MUST
> -  * not have a Content-Length (rfc 7230
> 3.3.3)
> -  */
> - if (desc->http_method ==
> HTTP_METHOD_RESPONSE && (
> - ((desc->http_status >= 100 &&
> - desc->http_status < 200) ||
> - desc->http_status == 204))) {
> - relay_abort_http(con, 500,
> - "Internal Server Error", 0);
> - goto abort;
> - }
>   /*
>* Need to read data from the client after
> the
>* HTTP header.
> @@ -349,6 +336,23 @@ relay_read_http(struct bufferevent *bev, void
> *arg)
>   relay_abort_http(con, 500, errstr,
> 0);
>   goto abort;
>   }
> + /*
> +  * response with a status code of 1xx
> +  * (Informational) or 204 (No Content) MUST
> +  * not have a Content-Length (rfc 7230
> 3.3.3)
> +  * Instead we check for value != 0 because
> there are
> +  * servers that do not follow the rfc and
> send
> +  * Content-Length: 0.
> +  */
> + if (desc->http_method ==
> HTTP_METHOD_RESPONSE && (
> + ((desc->http_status >= 100 &&
> + desc->http_status < 200) ||
> + desc->http_status == 204)) &&
> + cre->toread != 0) {
> + relay_abort_http(con, 502,
> + "Bad Gateway", 0);
> + goto abort;
> + }
>   }
>   lookup:
>   if (strcasecmp("Transfer-Encoding", key) == 0 &&
> 

Re: syslogd UDP EADDRNOTAVAIL

2017-09-29 Thread Rivo Nurges
Hi!

I have seen it number of times but haven't had time to investigate it
further. I have another ugly workaround to fix it. In my case it
happens because the route to the syslog target is learned via bgp and
the bgp is not up when syslogd tries to send first message. Your patch
fixes it.

Rivo

On Fri, 2017-09-29 at 13:44 +0200, Alexander Bluhm wrote:
> Hi,
> 
> A customer has seen a "Can't assign requested address" error from
> syslogd(8) at boot time and then sending messages per UDP did not
> work.  It is a carp(4) setup.
> 
> So I would suggest to add EADDRNOTAVAIL to the error numbers that
> are ignored when doing UDP sendto(2).  Otherwise syslogd would no
> longer send to this destination after the error occured once.
> 
> ok?
> 
> bluhm
> 
> Index: usr.sbin/syslogd/syslogd.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
> retrieving revision 1.249
> diff -u -p -r1.249 syslogd.c
> --- usr.sbin/syslogd/syslogd.c27 Sep 2017 15:09:48 -  
> 1.249
> +++ usr.sbin/syslogd/syslogd.c29 Sep 2017 11:32:51 -
> @@ -1957,6 +1957,7 @@ fprintlog(struct filed *f, int flags, ch
>   (struct sockaddr *)>f_un.f_forw.f_addr,
>   f->f_un.f_forw.f_addr.ss_len) != l) {
>   switch (errno) {
> + case EADDRNOTAVAIL:
>   case EHOSTDOWN:
>   case EHOSTUNREACH:
>   case ENETDOWN:
> 

Re: relayd interrupted transfers

2017-08-25 Thread Rivo Nurges
Hi!

Your version works for me.

Rivo

On 24/08/2017, 17:10, "Alexander Bluhm" <alexander.bl...@gmx.net> wrote:

On Thu, Aug 24, 2017 at 12:44:27PM +0000, Rivo Nurges wrote:
> This will fix my problem and regress still passes.

Yes this also works for me.

I think the variable name "dst" is not good.  Normally it refers
to someting on the cre->dst side.  As the buffer is on our side, I
think EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) is better.

I was also wondering whether it is correct to skip the
bufferevent_enable(cre->dst->bev, EV_READ) further down.  Would
your current diff create pumped dataflow behavior as the output
buffer must be completely empty before new data is read?

The relay_splice() checks for the buffer length itself and disables
reading if the buffers are not empty.  This does not work due to
the bufferevent_enable(cre->dst->bev, EV_READ) which was added
later.

So I think the logic should look like this.  Does this work
for you?

bluhm

Index: usr.sbin/relayd/relay.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.225
diff -u -p -r1.225 relay.c
--- usr.sbin/relayd/relay.c 9 Aug 2017 21:29:17 -   1.225
+++ usr.sbin/relayd/relay.c 24 Aug 2017 14:02:38 -
@@ -791,12 +791,12 @@ relay_write(struct bufferevent *bev, voi
 
getmonotime(>se_tv_last);
 
-   if (con->se_done)
+   if (con->se_done && EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) == 0)
goto done;
-   if (relay_splice(cre->dst) == -1)
-   goto fail;
if (cre->dst->bev)
bufferevent_enable(cre->dst->bev, EV_READ);
+   if (relay_splice(cre->dst) == -1)
+   goto fail;
 
return;
  done:




Re: relayd interrupted transfers

2017-08-24 Thread Rivo Nurges
Hi!

This will fix my problem and regress still passes.

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.225
diff -u -p -r1.225 relay.c
--- usr.sbin/relayd/relay.c 9 Aug 2017 21:29:17 -   1.225
+++ usr.sbin/relayd/relay.c 24 Aug 2017 12:41:55 -
@@ -788,9 +788,12 @@ relay_write(struct bufferevent *bev, voi
 {
struct ctl_relay_event  *cre = arg;
struct rsession *con = cre->con;
+   struct evbuffer *dst = EVBUFFER_OUTPUT(bev);
 
getmonotime(>se_tv_last);
 
+   if (EVBUFFER_LENGTH(dst))
+   return;
if (con->se_done)
goto done;
if (relay_splice(cre->dst) == -1)


Rivo

On 23/08/2017, 14:42, "Alexander Bluhm" <alexander.bl...@gmx.net> wrote:

On Tue, Aug 22, 2017 at 05:31:17PM +, Rivo Nurges wrote:
> relay_error() sets se_done even if write buffer is not drained and
> relay_write() will close the connection if se_done is set

I have seen a sporadic fail with chunked encoding in the daily
regression test run.  So something might be wrong.  Your idea of
not closing the relay if there is data in the buffer, makes sense.

Unfortunately the regression tests in /usr/src/regress/usr.sbin/relayd
fail with your patch.  It hangs as the EOF is not properly propagated.
I think the change in relay_error() affects too much.

bluhm




Re: relayd interrupted transfers

2017-08-23 Thread Rivo Nurges
Hi!

I'll look into it.

Rivo

On 23/08/2017, 14:42, "Alexander Bluhm" <alexander.bl...@gmx.net> wrote:

On Tue, Aug 22, 2017 at 05:31:17PM +0000, Rivo Nurges wrote:
> relay_error() sets se_done even if write buffer is not drained and
> relay_write() will close the connection if se_done is set

I have seen a sporadic fail with chunked encoding in the daily
regression test run.  So something might be wrong.  Your idea of
not closing the relay if there is data in the buffer, makes sense.

Unfortunately the regression tests in /usr/src/regress/usr.sbin/relayd
fail with your patch.  It hangs as the EOF is not properly propagated.
I think the change in relay_error() affects too much.

bluhm




relayd interrupted transfers

2017-08-22 Thread Rivo Nurges
Hi!

relay_error() sets se_done even if write buffer is not drained and
relay_write() will close the connection if se_done is set

I have a case with 76k json payload where relay_error() detects EOF
on read socket, sets so_done but write socket is not drained yet
and socket is closed before all the content is transfered.

debug output:
version: HTTP/1.1 rescode: 200 resmsg: OK
relay_writeheader_kv: Connection: close
relay_writeheader_kv: Content-Length: 76854
relay_writeheader_kv: Content-Type: application/json;charset=utf-8
relay_read_httpcontent: session 1: size 3752, to read 76854
relay_read_httpcontent: done, size 3752, to read 73102
relay_read_httpcontent: session 1: size 16384, to read 73102
relay_read_httpcontent: done, size 16384, to read 56718
relay_write buffer len 4081 se_done 0
relay_read_httpcontent: session 1: size 56718, to read 56718
relay_read_httpcontent: done, size 56718, to read 0
relay_read_http: session 1: size 0, to read -2
relay_write buffer len 44415 se_done 0
relay_write buffer len 28031 se_done 1
relay test, session 1 (1 active), 0, 1.2.3.4 -> 5.5.66.66:, last write 
(done), GET

fix:
Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.225
diff -u -p -r1.225 relay.c
--- usr.sbin/relayd/relay.c 9 Aug 2017 21:29:17 -   1.225
+++ usr.sbin/relayd/relay.c 22 Aug 2017 17:07:33 -
@@ -788,9 +788,12 @@ relay_write(struct bufferevent *bev, voi
 {
struct ctl_relay_event  *cre = arg;
struct rsession *con = cre->con;
+   struct evbuffer *dst = EVBUFFER_OUTPUT(bev);
 
getmonotime(>se_tv_last);
 
+   if (EVBUFFER_LENGTH(dst))
+   return;
if (con->se_done)
goto done;
if (relay_splice(cre->dst) == -1)
@@ -962,7 +965,6 @@ relay_error(struct bufferevent *bev, sho
 {
struct ctl_relay_event  *cre = arg;
struct rsession *con = cre->con;
-   struct evbuffer *dst;
 
if (error & EVBUFFER_TIMEOUT) {
if (cre->splicelen >= 0) {
@@ -1017,9 +1019,7 @@ relay_error(struct bufferevent *bev, sho
 
con->se_done = 1;
if (cre->dst->bev != NULL) {
-   dst = EVBUFFER_OUTPUT(cre->dst->bev);
-   if (EVBUFFER_LENGTH(dst))
-   return;
+   return;
} else if (cre->toread == TOREAD_UNLIMITED || cre->toread == 0)
return;
 


Rivo



fix relayd dns protocol

2017-06-29 Thread Rivo Nurges
Hi!

config_setrelay>relay_privinit>relay_udp_privinit doesn't set env
since env isn't set in relay.c yet, causing dns relay to SIGSEGV
in relay_udp_server. Move setting env to relay_udp_init.

Rivo

Index: usr.sbin/relayd/relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.221
diff -u -p -r1.221 relay.c
--- usr.sbin/relayd/relay.c 28 May 2017 10:39:15 -  1.221
+++ usr.sbin/relayd/relay.c 29 Jun 2017 20:58:08 -
@@ -285,7 +285,7 @@ relay_privinit(struct relay *rlay)
 
switch (rlay->rl_proto->type) {
case RELAY_PROTO_DNS:
-   relay_udp_privinit(env, rlay);
+   relay_udp_privinit(rlay);
break;
case RELAY_PROTO_TCP:
break;
@@ -445,7 +445,7 @@ relay_launch(void)
 
switch (rlay->rl_proto->type) {
case RELAY_PROTO_DNS:
-   relay_udp_init(rlay);
+   relay_udp_init(env, rlay);
break;
case RELAY_PROTO_TCP:
case RELAY_PROTO_HTTP:
Index: usr.sbin/relayd/relay_udp.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_udp.c,v
retrieving revision 1.46
diff -u -p -r1.46 relay_udp.c
--- usr.sbin/relayd/relay_udp.c 28 May 2017 10:39:15 -  1.46
+++ usr.sbin/relayd/relay_udp.c 29 Jun 2017 20:58:08 -
@@ -58,20 +58,20 @@ void relay_dns_result(struct rsession 
 int relay_dns_cmp(struct rsession *, struct rsession *);
 
 void
-relay_udp_privinit(struct relayd *x_env, struct relay *rlay)
+relay_udp_privinit(struct relay *rlay)
 {
-   if (env == NULL)
-   env = x_env;
-
if (rlay->rl_conf.flags & F_TLS)
fatalx("tls over udp is not supported");
rlay->rl_conf.flags |= F_UDP;
 }
 
 void
-relay_udp_init(struct relay *rlay)
+relay_udp_init(struct relayd *x_env, struct relay *rlay)
 {
struct protocol *proto = rlay->rl_proto;
+
+   if (env == NULL)
+   env = x_env;
 
switch (proto->type) {
case RELAY_PROTO_DNS:
Index: usr.sbin/relayd/relayd.h
===
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.240
diff -u -p -r1.240 relayd.h
--- usr.sbin/relayd/relayd.h27 May 2017 08:33:25 -  1.240
+++ usr.sbin/relayd/relayd.h29 Jun 2017 20:58:08 -
@@ -1218,8 +1218,8 @@ intrelay_httpdesc_init(struct ctl_rela
 ssize_t relay_http_time(time_t, char *, size_t);
 
 /* relay_udp.c */
-voidrelay_udp_privinit(struct relayd *, struct relay *);
-voidrelay_udp_init(struct relay *);
+voidrelay_udp_privinit(struct relay *);
+voidrelay_udp_init(struct relayd *, struct relay *);
 int relay_udp_bind(struct sockaddr_storage *, in_port_t,
struct protocol *);
 voidrelay_udp_server(int, short, void *);




Re: snmpd agentx fixes

2017-04-13 Thread Rivo Nurges
Hi!

I have upgraded about 20 boxes to current with the patch and everything works.

Rivo

On 10/04/2017, 03:27, "Jeremie Courreges-Anglas" <j...@wxcvbn.org> wrote:


Hi,

when implementing support for multiple listening sockets, I broke AgentX
support in a rather silly way.  AgentX support is only used by relayd in
    base.

Rivo Nurges (in cc) contacted me about this.  Thanks to him and reyk@
for helping me reproduce the issue.

The config below helps reproduce the problem.

# cat /etc/snmpd.conf
socket "/var/run/agentx.sock" agentx
# cat /etc/relayd.conf
snmp
table  { 127.0.0.1 }
relay "bar" {
listen on 0.0.0.0 port 1234
forward to  check icmp
}
#

There are two diffs below.

The first part is the fix for the multiple socket support.  The issue is
that in control.c SNMP data is sent down the... AgentX socket.  This
obviously doesn't fly.  We need to know which socket to use when sending
SNMP replies, so let's store it in the snmp_message context (which
already stores the remote and local addresses).  Too obvious?

The first problem tends to hide another bug: an uninitialized variable
in trap.c.  This fix was written by Rivo Nurges.

Thoughts / ok?


Index: control.c
===
RCS file: /d/cvs/src/usr.sbin/snmpd/control.c,v
retrieving revision 1.41
diff -u -p -r1.41 control.c
--- control.c   9 Jan 2017 14:49:22 -   1.41
+++ control.c   9 Apr 2017 18:28:23 -
@@ -592,7 +592,7 @@ control_dispatch_agentx(int fd, short ev
}
}
  dispatch:
-   snmpe_dispatchmsg(msg, fd);
+   snmpe_dispatchmsg(msg);
break;
}
 
Index: snmpd.h
===
RCS file: /d/cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.74
diff -u -p -r1.74 snmpd.h
--- snmpd.h 9 Jan 2017 14:49:22 -   1.74
+++ snmpd.h 9 Apr 2017 18:28:23 -
@@ -401,6 +401,7 @@ struct pfr_buffer {
 #define MSG_REPORT(m)  (((m)->sm_flags & SNMP_MSGFLAG_REPORT) 
!= 0)
 
 struct snmp_message {
+   int  sm_sock;
struct sockaddr_storage  sm_ss;
socklen_tsm_slen;
char sm_host[HOST_NAME_MAX+1];
@@ -660,7 +661,7 @@ struct kif_arp  *karp_getaddr(struct sock
 /* snmpe.c */
 voidsnmpe(struct privsep *, struct privsep_proc *);
 voidsnmpe_shutdown(void);
-voidsnmpe_dispatchmsg(struct snmp_message *, int);
+voidsnmpe_dispatchmsg(struct snmp_message *);
 
 /* trap.c */
 voidtrap_init(void);
Index: snmpe.c
===
RCS file: /d/cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.46
diff -u -p -r1.46 snmpe.c
--- snmpe.c 18 Nov 2016 16:16:39 -  1.46
+++ snmpe.c 9 Apr 2017 18:28:23 -
@@ -42,7 +42,7 @@
 voidsnmpe_init(struct privsep *, struct privsep_proc *, void *);
 int snmpe_parse(struct snmp_message *);
 int snmpe_parsevarbinds(struct snmp_message *);
-voidsnmpe_response(int, struct snmp_message *);
+voidsnmpe_response(struct snmp_message *);
 unsigned long
 snmpe_application(struct ber_element *);
 voidsnmpe_sig_handler(int sig, short, void *);
@@ -489,6 +489,7 @@ snmpe_recvmsg(int fd, short sig, void *a
if ((msg = calloc(1, sizeof(*msg))) == NULL)
return;
 
+   msg->sm_sock = fd;
msg->sm_slen = sizeof(msg->sm_ss);
if ((len = recvfromto(fd, msg->sm_data, sizeof(msg->sm_data), 0,
(struct sockaddr *)>sm_ss, >sm_slen,
@@ -520,7 +521,7 @@ snmpe_recvmsg(int fd, short sig, void *a
if (snmpe_parse(msg) == -1) {
if (msg->sm_usmerr != 0 && MSG_REPORT(msg)) {
usm_make_report(msg);
-   snmpe_response(fd, msg);
+   snmpe_response(msg);
return;
} else {
snmp_msgfree(msg);
@@ -528,22 +529,22 @@ snmpe_recvmsg(int fd, short sig, void *a
}
}
 
-   snmpe_dispatchmsg(msg, fd);
+   snmpe_dispatchmsg(msg);
 }
 
 void
-snmpe_dispatchmsg(struct snmp_message *msg, int sock)
+snmpe_dispatchmsg(struct snmp_message *msg)
 {
if (snmpe_parsevarbinds(msg) == 1)
return;
 
/* not dispatched to subagent; respond direct

Re: httpd: expand HTTP Host

2017-03-15 Thread Rivo Nurges
Hi!

New simplified version of the patch.

Test results:
HTTP 1.1 with Host:
HTTP/1.0 301 Moved Permanently
Location: https://testhttp.int/

HTTP 1.0 with Host:
HTTP/1.0 301 Moved Permanently
Location: https://testhttp.int/

HTTP 1.1 without Host:
HTTP/1.0 400 Bad Request

HTTP 1.0 without Host:
HTTP/1.0 301 Moved Permanently
Location: https://10.10.10.10/

GET /:
HTTP/1.0 400 Bad Request


Rivo

Index: usr.sbin/httpd/server_http.c
===
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.115
diff -u -p -r1.115 server_http.c
--- usr.sbin/httpd/server_http.c10 Mar 2017 21:06:43 -  1.115
+++ usr.sbin/httpd/server_http.c15 Mar 2017 17:51:14 -
@@ -1068,6 +1068,14 @@ server_expand_http(struct client *clt, c
if (ret != 0)
return (NULL);
}
+   if (strstr(val, "$HTTP_HOST") != NULL) {
+   if (desc->http_host == NULL)
+   return (NULL);
+   if ((str = url_encode(desc->http_host)) == NULL)
+   return (NULL);
+   expand_string(buf, len, "$HTTP_HOST", str);
+   free(str);
+   }
if (strstr(val, "$REMOTE_") != NULL) {
if (strstr(val, "$REMOTE_ADDR") != NULL) {
if (print_host(>clt_ss,
Index: usr.sbin/httpd/httpd.conf.5
===
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.79
diff -u -p -r1.79 httpd.conf.5
--- usr.sbin/httpd/httpd.conf.5 7 Feb 2017 12:27:42 -   1.79
+++ usr.sbin/httpd/httpd.conf.5 15 Mar 2017 17:51:14 -
@@ -221,6 +221,8 @@ The configured IP address of the server.
 The configured TCP server port of the server.
 .It Ic $SERVER_NAME
 The name of the server.
+.It Ic $HTTP_HOST
+The host from the HTTP Host header.
 .It Pf % Ar n
 The capture index
 .Ar n

begin-base64 644 http_host.diff
SW5kZXg6IHVzci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvdXNyLnNiaW4vaHR0cGQvc2VydmVyX2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS4xMTUKZGlmZiAtdSAtcCAtcjEuMTE1IHNlcnZlcl9odHRwLmMKLS0tIHVzci5zYmluL2h0
dHBkL3NlcnZlcl9odHRwLmMJMTAgTWFyIDIwMTcgMjE6MDY6NDMgLTAwMDAJMS4xMTUKKysrIHVz
ci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMJMTUgTWFyIDIwMTcgMTc6NTE6MTQgLTAwMDAKQEAg
LTEwNjgsNiArMTA2OCwxNCBAQCBzZXJ2ZXJfZXhwYW5kX2h0dHAoc3RydWN0IGNsaWVudCAqY2x0
LCBjCiAJCWlmIChyZXQgIT0gMCkKIAkJCXJldHVybiAoTlVMTCk7CiAJfQorCWlmIChzdHJzdHIo
dmFsLCAiJEhUVFBfSE9TVCIpICE9IE5VTEwpIHsKKwkJaWYgKGRlc2MtPmh0dHBfaG9zdCA9PSBO
VUxMKQorCQkJcmV0dXJuIChOVUxMKTsKKwkJaWYgKChzdHIgPSB1cmxfZW5jb2RlKGRlc2MtPmh0
dHBfaG9zdCkpID09IE5VTEwpCisJCQlyZXR1cm4gKE5VTEwpOworCQlleHBhbmRfc3RyaW5nKGJ1
ZiwgbGVuLCAiJEhUVFBfSE9TVCIsIHN0cik7CisJCWZyZWUoc3RyKTsKKwl9CiAJaWYgKHN0cnN0
cih2YWwsICIkUkVNT1RFXyIpICE9IE5VTEwpIHsKIAkJaWYgKHN0cnN0cih2YWwsICIkUkVNT1RF
X0FERFIiKSAhPSBOVUxMKSB7CiAJCQlpZiAocHJpbnRfaG9zdCgmY2x0LT5jbHRfc3MsCkluZGV4
OiB1c3Iuc2Jpbi9odHRwZC9odHRwZC5jb25mLjUKPT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTogL2N2cy9z
cmMvdXNyLnNiaW4vaHR0cGQvaHR0cGQuY29uZi41LHYKcmV0cmlldmluZyByZXZpc2lvbiAxLjc5
CmRpZmYgLXUgLXAgLXIxLjc5IGh0dHBkLmNvbmYuNQotLS0gdXNyLnNiaW4vaHR0cGQvaHR0cGQu
Y29uZi41CTcgRmViIDIwMTcgMTI6Mjc6NDIgLTAwMDAJMS43OQorKysgdXNyLnNiaW4vaHR0cGQv
aHR0cGQuY29uZi41CTE1IE1hciAyMDE3IDE3OjUxOjE0IC0wMDAwCkBAIC0yMjEsNiArMjIxLDgg
QEAgVGhlIGNvbmZpZ3VyZWQgSVAgYWRkcmVzcyBvZiB0aGUgc2VydmVyLgogVGhlIGNvbmZpZ3Vy
ZWQgVENQIHNlcnZlciBwb3J0IG9mIHRoZSBzZXJ2ZXIuCiAuSXQgSWMgJFNFUlZFUl9OQU1FCiBU
aGUgbmFtZSBvZiB0aGUgc2VydmVyLgorLkl0IEljICRIVFRQX0hPU1QKK1RoZSBob3N0IGZyb20g
dGhlIEhUVFAgSG9zdCBoZWFkZXIuCiAuSXQgUGYgJSBBciBuCiBUaGUgY2FwdHVyZSBpbmRleAog
LkFyIG4K
 



Re: httpd: expand HTTP Host

2017-03-13 Thread Rivo Nurges
Hi!

Sure. Should I create new patch?

Rivo

On 13/03/2017, 20:38, "Florian Obser" <flor...@openbsd.org> wrote:

On Mon, Mar 13, 2017 at 06:22:50PM +0000, Rivo Nurges wrote:
> Hi!
> 
> Host header is mandatory for HTTP 1.1 requests and httpd will return
> 400 Bad request without it. With HTTP 1.0 requests I get 301 to the
> IP the httpd is running on.
> 

right, so the
if (desc->http_host == NULL) {
can't actually happen.

how about

+   if (desc->http_host == NULL)
+   return (NULL)
+ 
+   if ((str = url_encode(desc->http_host)) == NULL)
...

that would be OK by me

> Connected to 10.XXX
> Escape character is '^]'.
> GET / HTTP/1.0\r\n\r\n
> 
> HTTP/1.0 301 Moved Permanently
> Date: Mon, 13 Mar 2017 18:20:48 GMT
> Server: OpenBSD httpd
> Connection: close
> Content-Type: text/html
> Content-Length: 443
> Location: https://10.XXX/
> 
> Rivo
> 
> On 13/03/2017, 20:10, "Florian Obser" <flor...@openbsd.org> wrote:
> 
> On Sat, Mar 11, 2017 at 06:11:53PM +, Rivo Nurges wrote:
> > Hi!
> > 
> > Following will add possibility to expand $HTTP_HOST to the HTTP
> > Host header in "block return".
> > 
> > In my setup I have relayd on port 443 and httpd on 80. This patch
> > allows me to redirect http(httpd) to https(relayd) without knowing
> > the host.
> > 
> > /etc/httpd.conf:
> > server "redirect" {
> >   listen on * port 80
> >   block return 301 "https://$HTTP_HOST$REQUEST_URI;
> > }
> > 
> > Rivo
> > 
> > Index: usr.sbin/httpd/server_http.c
> > ===
> > RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
> > retrieving revision 1.115
> > diff -u -p -r1.115 server_http.c
> > --- usr.sbin/httpd/server_http.c10 Mar 2017 21:06:43 -  
1.115
> > +++ usr.sbin/httpd/server_http.c11 Mar 2017 17:51:23 -
> > @@ -1068,6 +1068,18 @@ server_expand_http(struct client *clt, c
> > if (ret != 0)
> > return (NULL);
> > }
> > +   if (strstr(val, "$HTTP_HOST") != NULL) {
> > +   if (desc->http_host == NULL) {
> > +   ret = expand_string(buf, len, "$HTTP_HOST", "");
> 
> This will not create a working redirect. Should we return 500 instead
> if there is no host header?
> 
> What is nginx doing in that case?
> 
> nginx has $http_host and $host, $host is assigned the host header and
> if that doesn't exist the server name. (Wouldn't help in your case
> since it would redirect to https://redirect/).
> 
> Other than this looks good.
> 
> > +   } else {
> > +   if ((str = url_encode(desc->http_host)) == NULL)
> > +   return (NULL);
> > +   ret = expand_string(buf, len, "$HTTP_HOST", 
str);
> > +   free(str);
> > +   }
> > +   if (ret != 0)
> > +   return (NULL);
> > +   }
> > if (strstr(val, "$REMOTE_") != NULL) {
> > if (strstr(val, "$REMOTE_ADDR") != NULL) {
> > if (print_host(>clt_ss,
> > Index: usr.sbin/httpd/httpd.conf.5
> > ===
> > RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
> > retrieving revision 1.79
> > diff -u -p -r1.79 httpd.conf.5
> > --- usr.sbin/httpd/httpd.conf.5 7 Feb 2017 12:27:42 -   
1.79
> > +++ usr.sbin/httpd/httpd.conf.5 11 Mar 2017 17:51:23 -
> > @@ -221,6 +221,8 @@ The configured IP address of the server.
> >  The configured TCP server port of the server.
> >  .It Ic $SERVER_NAME
> >  The name of the server.
> > +.It Ic $HTTP_HOST
> > +The host from the HTTP Host header.
>

Re: httpd: expand HTTP Host

2017-03-13 Thread Rivo Nurges
Hi!

Host header is mandatory for HTTP 1.1 requests and httpd will return
400 Bad request without it. With HTTP 1.0 requests I get 301 to the
IP the httpd is running on.

Connected to 10.XXX
Escape character is '^]'.
GET / HTTP/1.0\r\n\r\n

HTTP/1.0 301 Moved Permanently
Date: Mon, 13 Mar 2017 18:20:48 GMT
Server: OpenBSD httpd
Connection: close
Content-Type: text/html
Content-Length: 443
Location: https://10.XXX/

Rivo

On 13/03/2017, 20:10, "Florian Obser" <flor...@openbsd.org> wrote:

On Sat, Mar 11, 2017 at 06:11:53PM +0000, Rivo Nurges wrote:
> Hi!
> 
> Following will add possibility to expand $HTTP_HOST to the HTTP
> Host header in "block return".
> 
> In my setup I have relayd on port 443 and httpd on 80. This patch
> allows me to redirect http(httpd) to https(relayd) without knowing
> the host.
> 
> /etc/httpd.conf:
> server "redirect" {
>   listen on * port 80
>   block return 301 "https://$HTTP_HOST$REQUEST_URI;
> }
> 
> Rivo
> 
> Index: usr.sbin/httpd/server_http.c
> ===
> RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
> retrieving revision 1.115
> diff -u -p -r1.115 server_http.c
> --- usr.sbin/httpd/server_http.c  10 Mar 2017 21:06:43 -  1.115
> +++ usr.sbin/httpd/server_http.c  11 Mar 2017 17:51:23 -
> @@ -1068,6 +1068,18 @@ server_expand_http(struct client *clt, c
>   if (ret != 0)
>   return (NULL);
>   }
> + if (strstr(val, "$HTTP_HOST") != NULL) {
> + if (desc->http_host == NULL) {
> + ret = expand_string(buf, len, "$HTTP_HOST", "");

This will not create a working redirect. Should we return 500 instead
if there is no host header?

What is nginx doing in that case?

nginx has $http_host and $host, $host is assigned the host header and
if that doesn't exist the server name. (Wouldn't help in your case
since it would redirect to https://redirect/).

Other than this looks good.

> + } else {
> + if ((str = url_encode(desc->http_host)) == NULL)
> + return (NULL);
> + ret = expand_string(buf, len, "$HTTP_HOST", str);
> + free(str);
> + }
> + if (ret != 0)
> + return (NULL);
> + }
>   if (strstr(val, "$REMOTE_") != NULL) {
>   if (strstr(val, "$REMOTE_ADDR") != NULL) {
>   if (print_host(>clt_ss,
> Index: usr.sbin/httpd/httpd.conf.5
> ===
> RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
> retrieving revision 1.79
> diff -u -p -r1.79 httpd.conf.5
> --- usr.sbin/httpd/httpd.conf.5   7 Feb 2017 12:27:42 -   1.79
> +++ usr.sbin/httpd/httpd.conf.5   11 Mar 2017 17:51:23 -
> @@ -221,6 +221,8 @@ The configured IP address of the server.
>  The configured TCP server port of the server.
>  .It Ic $SERVER_NAME
>  The name of the server.
> +.It Ic $HTTP_HOST
> +The host from the HTTP Host header.
>  .It Pf % Ar n
>  The capture index
>  .Ar n
> 
> begin-base64 644 http_host.diff
> 
SW5kZXg6IHVzci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
> 
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
> 
L2N2cy9zcmMvdXNyLnNiaW4vaHR0cGQvc2VydmVyX2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
> 
b24gMS4xMTUKZGlmZiAtdSAtcCAtcjEuMTE1IHNlcnZlcl9odHRwLmMKLS0tIHVzci5zYmluL2h0
> 
dHBkL3NlcnZlcl9odHRwLmMJMTAgTWFyIDIwMTcgMjE6MDY6NDMgLTAwMDAJMS4xMTUKKysrIHVz
> 
ci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMJMTEgTWFyIDIwMTcgMTc6NTE6MjMgLTAwMDAKQEAg
> 
LTEwNjgsNiArMTA2OCwxOCBAQCBzZXJ2ZXJfZXhwYW5kX2h0dHAoc3RydWN0IGNsaWVudCAqY2x0
> 
LCBjCiAJCWlmIChyZXQgIT0gMCkKIAkJCXJldHVybiAoTlVMTCk7CiAJfQorCWlmIChzdHJzdHIo
> 
dmFsLCAiJEhUVFBfSE9TVCIpICE9IE5VTEwpIHsKKwkJaWYgKGRlc2MtPmh0dHBfaG9zdCA9PSBO
> 
VUxMKSB7CisJCQlyZXQgPSBleHBhbmRfc3RyaW5nKGJ1ZiwgbGVuLCAiJEhUVFBfSE9TVCIsICIi
> 
KTsKKwkJfSBlbHNlIHsKKwkJCWlmICgoc3RyID0gdXJsX2VuY29kZShkZXNjLT5odHRwX2hvc3Qp
> 
KSA9PSBOVUxMKQorCQkJCXJldHVybiAoTlVMTCk7CisJCQlyZXQgPSBleHBhbmRfc3RyaW5nKGJ1
> 
ZiwgbGVuLCAiJEhUVFBfSE9TVCIsIHN0cik7CisJCQlmcmVlKHN0cik7CisJCX0KKwkJaWYgKHJl
> 
dCAhPSAwKQorCQkJcmV0dXJuIChOVUxMKTsKKwl9CiAJaWYgKHN0cnN0cih2YWwsICIkUkVNT1RF
> 
XyIpICE9IE5VTEwpIHsKIAkJaWYgKHN0cnN0cih2YWwsICIkUkVNT1RFX0FERFIiKSAhPSBOVU

Re: disklabel template on miniroot

2017-03-11 Thread Rivo Nurges
Hi!

It looks a bit silly to copy the template from one folder to another with ftp, 
but yeah, it works. Thanks for the hint.

Rivo

On 12/03/2017, 00:13, "owner-t...@openbsd.org on behalf of Theo Buehler" 
<owner-t...@openbsd.org on behalf of t...@math.ethz.ch> wrote:

On Sat, Mar 11, 2017 at 09:59:09PM +0000, Rivo Nurges wrote:
> Hi!
> 
> Following will add support for disklabel template on miniroot.

Can't you achieve the same by adding

URL to autopartitioning template for disklabel = file:///disklabel.auto

to your auto_{install,upgrade}.conf ?

> 
> Rivo
> 
> Index: distrib/miniroot/install.sub
> ===
> RCS file: /cvs/src/distrib/miniroot/install.sub,v
> retrieving revision 1.987
> diff -u -p -r1.987 install.sub
> --- distrib/miniroot/install.sub  10 Mar 2017 22:34:09 -  1.987
> +++ distrib/miniroot/install.sub  11 Mar 2017 21:56:42 -
> @@ -396,6 +396,11 @@ disklabel_autolayout() {
>   [[ $_disk != $ROOTDISK ]] && return
>  
>   while $AUTO; do
> + if [[ -f /disklabel.auto ]]; then
> + disklabel -T /disklabel.auto -F $_f -w -A $_disk && 
return
> + echo "Autopartitioning failed"
> + exit 1
> + fi
>   ask "URL to autopartitioning template for disklabel?" none
>   [[ $resp == none ]] && break
>   if ! $FTP_TLS && [[ $resp == https://* ]]; then
> Index: share/man/man8/autoinstall.8
> ===
> RCS file: /cvs/src/share/man/man8/autoinstall.8,v
> retrieving revision 1.21
> diff -u -p -r1.21 autoinstall.8
> --- share/man/man8/autoinstall.8  21 Jan 2017 06:00:38 -  1.21
> +++ share/man/man8/autoinstall.8  11 Mar 2017 21:56:42 -
> @@ -58,6 +58,11 @@ behaves as if the machine is netbooted, 
>  In case both files exist,
>  .Pa /auto_install.conf
>  takes precedence.
> +If
> +.Pa /disklabel.auto
> +is found
> +.Nm
> +will use it as the autopartitioning template.
>  .Pp
>  .Nm
>  uses HTTP to fetch one of the files
> @@ -204,6 +209,8 @@ configuration file
>  response file for unattended installation
>  .It Pa upgrade.conf
>  response file for unattended upgrade
> +.It Pa disklabel.auto
> +autopartitioning template for unattended installation
>  .El
>  .Sh EXAMPLES
>  A typical





disklabel template on miniroot

2017-03-11 Thread Rivo Nurges
Hi!

Following will add support for disklabel template on miniroot.

Rivo

Index: distrib/miniroot/install.sub
===
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.987
diff -u -p -r1.987 install.sub
--- distrib/miniroot/install.sub10 Mar 2017 22:34:09 -  1.987
+++ distrib/miniroot/install.sub11 Mar 2017 21:56:42 -
@@ -396,6 +396,11 @@ disklabel_autolayout() {
[[ $_disk != $ROOTDISK ]] && return
 
while $AUTO; do
+   if [[ -f /disklabel.auto ]]; then
+   disklabel -T /disklabel.auto -F $_f -w -A $_disk && 
return
+   echo "Autopartitioning failed"
+   exit 1
+   fi
ask "URL to autopartitioning template for disklabel?" none
[[ $resp == none ]] && break
if ! $FTP_TLS && [[ $resp == https://* ]]; then
Index: share/man/man8/autoinstall.8
===
RCS file: /cvs/src/share/man/man8/autoinstall.8,v
retrieving revision 1.21
diff -u -p -r1.21 autoinstall.8
--- share/man/man8/autoinstall.821 Jan 2017 06:00:38 -  1.21
+++ share/man/man8/autoinstall.811 Mar 2017 21:56:42 -
@@ -58,6 +58,11 @@ behaves as if the machine is netbooted, 
 In case both files exist,
 .Pa /auto_install.conf
 takes precedence.
+If
+.Pa /disklabel.auto
+is found
+.Nm
+will use it as the autopartitioning template.
 .Pp
 .Nm
 uses HTTP to fetch one of the files
@@ -204,6 +209,8 @@ configuration file
 response file for unattended installation
 .It Pa upgrade.conf
 response file for unattended upgrade
+.It Pa disklabel.auto
+autopartitioning template for unattended installation
 .El
 .Sh EXAMPLES
 A typical


begin-base64 644 install_autolabel.diff
SW5kZXg6IGRpc3RyaWIvbWluaXJvb3QvaW5zdGFsbC5zdWIKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvZGlzdHJpYi9taW5pcm9vdC9pbnN0YWxsLnN1Yix2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS45ODcKZGlmZiAtdSAtcCAtcjEuOTg3IGluc3RhbGwuc3ViCi0tLSBkaXN0cmliL21pbmly
b290L2luc3RhbGwuc3ViCTEwIE1hciAyMDE3IDIyOjM0OjA5IC0wMDAwCTEuOTg3CisrKyBkaXN0
cmliL21pbmlyb290L2luc3RhbGwuc3ViCTExIE1hciAyMDE3IDIxOjU2OjQyIC0wMDAwCkBAIC0z
OTYsNiArMzk2LDExIEBAIGRpc2tsYWJlbF9hdXRvbGF5b3V0KCkgewogCVtbICRfZGlzayAhPSAk
Uk9PVERJU0sgXV0gJiYgcmV0dXJuCiAKIAl3aGlsZSAkQVVUTzsgZG8KKwkJaWYgW1sgLWYgL2Rp
c2tsYWJlbC5hdXRvIF1dOyB0aGVuCisJCQlkaXNrbGFiZWwgLVQgL2Rpc2tsYWJlbC5hdXRvIC1G
ICRfZiAtdyAtQSAkX2Rpc2sgJiYgcmV0dXJuCisJCQllY2hvICJBdXRvcGFydGl0aW9uaW5nIGZh
aWxlZCIKKwkJCWV4aXQgMQorCQlmaQogCQlhc2sgIlVSTCB0byBhdXRvcGFydGl0aW9uaW5nIHRl
bXBsYXRlIGZvciBkaXNrbGFiZWw/IiBub25lCiAJCVtbICRyZXNwID09IG5vbmUgXV0gJiYgYnJl
YWsKIAkJaWYgISAkRlRQX1RMUyAmJiBbWyAkcmVzcCA9PSBodHRwczovLyogXV07IHRoZW4KSW5k
ZXg6IHNoYXJlL21hbi9tYW44L2F1dG9pbnN0YWxsLjgKPT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTogL2N2
cy9zcmMvc2hhcmUvbWFuL21hbjgvYXV0b2luc3RhbGwuOCx2CnJldHJpZXZpbmcgcmV2aXNpb24g
MS4yMQpkaWZmIC11IC1wIC1yMS4yMSBhdXRvaW5zdGFsbC44Ci0tLSBzaGFyZS9tYW4vbWFuOC9h
dXRvaW5zdGFsbC44CTIxIEphbiAyMDE3IDA2OjAwOjM4IC0wMDAwCTEuMjEKKysrIHNoYXJlL21h
bi9tYW44L2F1dG9pbnN0YWxsLjgJMTEgTWFyIDIwMTcgMjE6NTY6NDIgLTAwMDAKQEAgLTU4LDYg
KzU4LDExIEBAIGJlaGF2ZXMgYXMgaWYgdGhlIG1hY2hpbmUgaXMgbmV0Ym9vdGVkLCAKIEluIGNh
c2UgYm90aCBmaWxlcyBleGlzdCwKIC5QYSAvYXV0b19pbnN0YWxsLmNvbmYKIHRha2VzIHByZWNl
ZGVuY2UuCitJZgorLlBhIC9kaXNrbGFiZWwuYXV0bworaXMgZm91bmQKKy5ObQord2lsbCB1c2Ug
aXQgYXMgdGhlIGF1dG9wYXJ0aXRpb25pbmcgdGVtcGxhdGUuCiAuUHAKIC5ObQogdXNlcyBIVFRQ
IHRvIGZldGNoIG9uZSBvZiB0aGUgZmlsZXMKQEAgLTIwNCw2ICsyMDksOCBAQCBjb25maWd1cmF0
aW9uIGZpbGUKIHJlc3BvbnNlIGZpbGUgZm9yIHVuYXR0ZW5kZWQgaW5zdGFsbGF0aW9uCiAuSXQg
UGEgdXBncmFkZS5jb25mCiByZXNwb25zZSBmaWxlIGZvciB1bmF0dGVuZGVkIHVwZ3JhZGUKKy5J
dCBQYSBkaXNrbGFiZWwuYXV0bworYXV0b3BhcnRpdGlvbmluZyB0ZW1wbGF0ZSBmb3IgdW5hdHRl
bmRlZCBpbnN0YWxsYXRpb24KIC5FbAogLlNoIEVYQU1QTEVTCiBBIHR5cGljYWwK




httpd: expand HTTP Host

2017-03-11 Thread Rivo Nurges
Hi!

Following will add possibility to expand $HTTP_HOST to the HTTP
Host header in "block return".

In my setup I have relayd on port 443 and httpd on 80. This patch
allows me to redirect http(httpd) to https(relayd) without knowing
the host.

/etc/httpd.conf:
server "redirect" {
  listen on * port 80
  block return 301 "https://$HTTP_HOST$REQUEST_URI;
}

Rivo

Index: usr.sbin/httpd/server_http.c
===
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.115
diff -u -p -r1.115 server_http.c
--- usr.sbin/httpd/server_http.c10 Mar 2017 21:06:43 -  1.115
+++ usr.sbin/httpd/server_http.c11 Mar 2017 17:51:23 -
@@ -1068,6 +1068,18 @@ server_expand_http(struct client *clt, c
if (ret != 0)
return (NULL);
}
+   if (strstr(val, "$HTTP_HOST") != NULL) {
+   if (desc->http_host == NULL) {
+   ret = expand_string(buf, len, "$HTTP_HOST", "");
+   } else {
+   if ((str = url_encode(desc->http_host)) == NULL)
+   return (NULL);
+   ret = expand_string(buf, len, "$HTTP_HOST", str);
+   free(str);
+   }
+   if (ret != 0)
+   return (NULL);
+   }
if (strstr(val, "$REMOTE_") != NULL) {
if (strstr(val, "$REMOTE_ADDR") != NULL) {
if (print_host(>clt_ss,
Index: usr.sbin/httpd/httpd.conf.5
===
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.79
diff -u -p -r1.79 httpd.conf.5
--- usr.sbin/httpd/httpd.conf.5 7 Feb 2017 12:27:42 -   1.79
+++ usr.sbin/httpd/httpd.conf.5 11 Mar 2017 17:51:23 -
@@ -221,6 +221,8 @@ The configured IP address of the server.
 The configured TCP server port of the server.
 .It Ic $SERVER_NAME
 The name of the server.
+.It Ic $HTTP_HOST
+The host from the HTTP Host header.
 .It Pf % Ar n
 The capture index
 .Ar n

begin-base64 644 http_host.diff
SW5kZXg6IHVzci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTog
L2N2cy9zcmMvdXNyLnNiaW4vaHR0cGQvc2VydmVyX2h0dHAuYyx2CnJldHJpZXZpbmcgcmV2aXNp
b24gMS4xMTUKZGlmZiAtdSAtcCAtcjEuMTE1IHNlcnZlcl9odHRwLmMKLS0tIHVzci5zYmluL2h0
dHBkL3NlcnZlcl9odHRwLmMJMTAgTWFyIDIwMTcgMjE6MDY6NDMgLTAwMDAJMS4xMTUKKysrIHVz
ci5zYmluL2h0dHBkL3NlcnZlcl9odHRwLmMJMTEgTWFyIDIwMTcgMTc6NTE6MjMgLTAwMDAKQEAg
LTEwNjgsNiArMTA2OCwxOCBAQCBzZXJ2ZXJfZXhwYW5kX2h0dHAoc3RydWN0IGNsaWVudCAqY2x0
LCBjCiAJCWlmIChyZXQgIT0gMCkKIAkJCXJldHVybiAoTlVMTCk7CiAJfQorCWlmIChzdHJzdHIo
dmFsLCAiJEhUVFBfSE9TVCIpICE9IE5VTEwpIHsKKwkJaWYgKGRlc2MtPmh0dHBfaG9zdCA9PSBO
VUxMKSB7CisJCQlyZXQgPSBleHBhbmRfc3RyaW5nKGJ1ZiwgbGVuLCAiJEhUVFBfSE9TVCIsICIi
KTsKKwkJfSBlbHNlIHsKKwkJCWlmICgoc3RyID0gdXJsX2VuY29kZShkZXNjLT5odHRwX2hvc3Qp
KSA9PSBOVUxMKQorCQkJCXJldHVybiAoTlVMTCk7CisJCQlyZXQgPSBleHBhbmRfc3RyaW5nKGJ1
ZiwgbGVuLCAiJEhUVFBfSE9TVCIsIHN0cik7CisJCQlmcmVlKHN0cik7CisJCX0KKwkJaWYgKHJl
dCAhPSAwKQorCQkJcmV0dXJuIChOVUxMKTsKKwl9CiAJaWYgKHN0cnN0cih2YWwsICIkUkVNT1RF
XyIpICE9IE5VTEwpIHsKIAkJaWYgKHN0cnN0cih2YWwsICIkUkVNT1RFX0FERFIiKSAhPSBOVUxM
KSB7CiAJCQlpZiAocHJpbnRfaG9zdCgmY2x0LT5jbHRfc3MsCkluZGV4OiB1c3Iuc2Jpbi9odHRw
ZC9odHRwZC5jb25mLjUKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTogL2N2cy9zcmMvdXNyLnNiaW4vaHR0
cGQvaHR0cGQuY29uZi41LHYKcmV0cmlldmluZyByZXZpc2lvbiAxLjc5CmRpZmYgLXUgLXAgLXIx
Ljc5IGh0dHBkLmNvbmYuNQotLS0gdXNyLnNiaW4vaHR0cGQvaHR0cGQuY29uZi41CTcgRmViIDIw
MTcgMTI6Mjc6NDIgLTAwMDAJMS43OQorKysgdXNyLnNiaW4vaHR0cGQvaHR0cGQuY29uZi41CTEx
IE1hciAyMDE3IDE3OjUxOjIzIC0wMDAwCkBAIC0yMjEsNiArMjIxLDggQEAgVGhlIGNvbmZpZ3Vy
ZWQgSVAgYWRkcmVzcyBvZiB0aGUgc2VydmVyLgogVGhlIGNvbmZpZ3VyZWQgVENQIHNlcnZlciBw
b3J0IG9mIHRoZSBzZXJ2ZXIuCiAuSXQgSWMgJFNFUlZFUl9OQU1FCiBUaGUgbmFtZSBvZiB0aGUg
c2VydmVyLgorLkl0IEljICRIVFRQX0hPU1QKK1RoZSBob3N0IGZyb20gdGhlIEhUVFAgSG9zdCBo
ZWFkZXIuCiAuSXQgUGYgJSBBciBuCiBUaGUgY2FwdHVyZSBpbmRleAogLkFyIG4K




bgpd and indirect nexthops

2016-11-03 Thread Rivo Nurges
Hi!

I have ibgp setup where I receive number of routes with indirect nexthops.
"nexthop qualify via bgp" is configured. I'm using snapshot from 31.11.2016 and 
current bgpd sources.

When I start bgpd it usually comes up with either some or none of the indirect 
nexthops resolved:
# bgpctl show nex
Flags: * = nexthop valid

  Nexthop Route  Prio Gateway Iface
  10.150.0.10
* 10.150.0.12 10.150.0.0/2348 10.150.8.1
<~50 nexthops some working some not removed>
* 10.150.8.1  10.150.8.0/24 4 connected   vio0 (UP, active)

"bgpctl reload" always fixes the problem and all nexthops are resolved to 
10.150.0.0/23 -> 10.150.8.1

I have tried to find a way to fix it properly but so far I have managed to get 
it working with following definitely wrong patch.
There seems to be race somewhere between nexthop insertion and validation.
Any idea where should I look or what to check?

vio0: flags=8843 mtu 1500
lladdr 55:54:00:0b:39:f1
index 1 priority 0 llprio 3
groups: core egress
media: Ethernet autoselect
status: active
inet 10.150.8.5 netmask 0xff00 broadcast 10.150.8.255

config:
AS 65001
router-id 10.150.8.5
nexthop qualify via bgp
network inet connected
neighbor 10.150.8.1 {
  remote-as 65001
}
match from any prefix 0.0.0.0/0 prefixlen >= 1 set rtlabel INT
match to any set localpref 90

Index: kroute.c
===
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.210
diff -u -p -r1.210 kroute.c
--- kroute.c5 Oct 2016 07:38:06 -   1.210
+++ kroute.c3 Nov 2016 19:15:49 -
@@ -897,6 +897,8 @@ kr_nexthop_add(u_int rtableid, struct bg
return (-1);
}

+   RB_FOREACH(h, knexthop_tree, KT2KNT(kt))
+   knexthop_validate(kt, h);
return (0);
}



Re: thinkpad adaptive keyboard patch

2014-03-24 Thread rivo nurges
On Mon, Mar 17, 2014 at 07:11:09PM +, rivo nurges wrote:

Hi!

 New 2nd generation Lenovo X1 Carbon has touchable lcd strip instead
 of the F1-12 keys and the multimedia keys. It has 5 modes with tons
 of useless buttons triggering acpi hotkey events and 6th inactive
 mode.
 
 This patch adds support for switching between the Home and the
 Function modes. The Function mode has the standard F1-12 buttons
 and the Home mode has Volume, Mute and Brightness buttons. Other
 functions of the the Home mode are ignored. On power up BIOS activates
 the Function mode for us, on suspend it goes to the inactive mode
 and we need to reenable it when coming from suspend.
 
 The patch has been tested on X1 Carbon, X220 and X61s

New version. Style fixes suggested by jcs@, no functional changes.

-- 
rix


Index: sys/dev/acpi/acpithinkpad.c
===
RCS file: /OpenBSD/src/sys/dev/acpi/acpithinkpad.c,v
retrieving revision 1.34
diff -u -p -r1.34 acpithinkpad.c
--- sys/dev/acpi/acpithinkpad.c 4 Nov 2013 11:57:26 -   1.34
+++ sys/dev/acpi/acpithinkpad.c 24 Mar 2014 20:14:50 -
@@ -30,7 +30,8 @@
 #include audio.h
 #include wskbd.h
 
-#defineTHINKPAD_HKEY_VERSION   0x0100
+#defineTHINKPAD_HKEY_VERSION1  0x0100
+#defineTHINKPAD_HKEY_VERSION2  0x0200
 
 #defineTHINKPAD_CMOS_VOLUME_DOWN   0x00
 #defineTHINKPAD_CMOS_VOLUME_UP 0x01
@@ -65,6 +66,15 @@
 #defineTHINKPAD_BUTTON_MICROPHONE_MUTE 0x101b
 #defineTHINKPAD_BUTTON_FN_F11  0x100b
 #defineTHINKPAD_BUTTON_HIBERNATE   0x100c
+#defineTHINKPAD_ADAPTIVE_NEXT  0x1101
+#defineTHINKPAD_ADAPTIVE_QUICK 0x1102
+#defineTHINKPAD_ADAPTIVE_SNIP  0x1105
+#defineTHINKPAD_ADAPTIVE_VOICE 0x1108
+#defineTHINKPAD_ADAPTIVE_GESTURES  0x110a
+#defineTHINKPAD_ADAPTIVE_SETTINGS  0x110e
+#defineTHINKPAD_ADAPTIVE_TAB   0x110f
+#defineTHINKPAD_ADAPTIVE_REFRESH   0x1110
+#defineTHINKPAD_ADAPTIVE_BACK  0x
 #define THINKPAD_PORT_REPL_DOCKED  0x4010
 #define THINKPAD_PORT_REPL_UNDOCKED0x4011
 #defineTHINKPAD_LID_OPEN   0x5001
@@ -85,6 +95,9 @@
 #define THINKPAD_ECOFFSET_FANLO0x84
 #define THINKPAD_ECOFFSET_FANHI0x85
 
+#defineTHINKPAD_ADAPTIVE_MODE_HOME 1
+#defineTHINKPAD_ADAPTIVE_MODE_FUNCTION 3
+
 struct acpithinkpad_softc {
struct devicesc_dev;
 
@@ -110,6 +123,8 @@ int thinkpad_volume_up(struct acpithinkp
 intthinkpad_volume_mute(struct acpithinkpad_softc *);
 intthinkpad_brightness_up(struct acpithinkpad_softc *);
 intthinkpad_brightness_down(struct acpithinkpad_softc *);
+intthinkpad_adaptive_change(struct acpithinkpad_softc *);
+intthinkpad_activate(struct device *, int);
 
 voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc);
 voidthinkpad_sensor_refresh(void *);
@@ -119,7 +134,8 @@ extern int wskbd_set_mixervolume(long, l
 #endif
 
 struct cfattach acpithinkpad_ca = {
-   sizeof(struct acpithinkpad_softc), thinkpad_match, thinkpad_attach
+   sizeof(struct acpithinkpad_softc), thinkpad_match, thinkpad_attach,
+   NULL, thinkpad_activate
 };
 
 struct cfdriver acpithinkpad_cd = {
@@ -144,7 +160,7 @@ thinkpad_match(struct device *parent, vo
MHKV, 0, NULL, res))
return (0);
 
-   if (res != THINKPAD_HKEY_VERSION)
+   if (!(res == THINKPAD_HKEY_VERSION1 || res == THINKPAD_HKEY_VERSION2))
return (0);
 
return (1);
@@ -328,6 +344,18 @@ thinkpad_hotkey(struct aml_node *node, i
 #endif
handled = 1;
break;
+   case THINKPAD_ADAPTIVE_NEXT:
+   case THINKPAD_ADAPTIVE_QUICK:
+   thinkpad_adaptive_change(sc);
+   handled = 1;
+   break;
+   case THINKPAD_ADAPTIVE_BACK:
+   case THINKPAD_ADAPTIVE_GESTURES:
+   case THINKPAD_ADAPTIVE_REFRESH:
+   case THINKPAD_ADAPTIVE_SETTINGS:
+   case THINKPAD_ADAPTIVE_SNIP:
+   case THINKPAD_ADAPTIVE_TAB:
+   case THINKPAD_ADAPTIVE_VOICE:
case THINKPAD_BACKLIGHT_CHANGED:
case THINKPAD_BRIGHTNESS_CHANGED:
case THINKPAD_BUTTON_BATTERY_INFO:
@@ -453,4 +481,50 @@ int
 thinkpad_brightness_down(struct acpithinkpad_softc *sc)
 {
return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_DOWN));
+}
+
+int
+thinkpad_adaptive_change(struct acpithinkpad_softc *sc)
+{
+   struct aml_value arg;
+   int64_t mode;
+
+   if (aml_evalinteger(sc-sc_acpi, sc-sc_devnode, GTRW,
+   0, NULL, mode)) {
+   printf(%s: couldn't get adaptive keyboard mode\n, 
DEVNAME(sc));
+   return (1

bgpctl show_attr bad length fix

2014-03-18 Thread rivo nurges
Hi!

When show_attr reads data length from provided data it reads carbage
to alen and fails afterwards. This patch fixes the problem by casting
the data to u_char. While at it I noticed data gets assigned twice.


bgpctl.c: /* bad imsg len how can that happen!? */
bgpctl.c: if (alen  len)
bgpctl.c:   errx(1, show_attr: bad length);

It can happen:D


Example failing prefix with long community list:
Before:
BGP routing table entry for 5.44.0.0/20
25478 31499 39812
Nexthop x.y.z.w (via 10.9.0.10) from x.y.z.w (x.y.z.w)
Origin IGP, metric 4200, localpref 60, weight 0, internal, valid, best
Last update: 00:12:11 ago
bgpctl: show_attr: bad length

After:
BGP routing table entry for 5.44.0.0/20
25478 31499 39812
Nexthop x.y.z.w (via 10.9.0.10) from x.y.z.w (x.y.z.w)
Origin IGP, metric 4200, localpref 60, weight 0, internal, valid, best
Last update: 00:11:13 ago
Communities: 0:5429 0:6719 0:8241 0:8636 0:8641 0:24955 0:25478 0:25532
0:29000 0:29319 0:30784 0:31225 0:41349 0:41475 0:42511 0:42754 0:43973 0:44020
0:44053 0:44281 0:47104 0:47119 0:47321 0:48166 0:48293 0:48297 0:48781 0:49060
0:49124 0:50384 0:50448 0:50577 0:50911 0:50952 0:56462 0:57073 0:57363 1299:150
3249:10643 3249:11000 3249:11001 3356:90 6854:1009 6854:1509 6854:1605 6854:1665
8359:2094 8631:8631 8744:52994 8744:53124 8744:53134 8744:59994 12389:6992
12389:7130 12389:7993 12389:8020 12389:8995 25478:10011 25478:10931 25478:24000
25478:29000 31133:10008 31133:25002
Originator Id: x.y.z.w
Cluster ID List: x.y.z.w z.x.y.w


-- 
rix



Index: usr.sbin/bgpctl/bgpctl.c
===
RCS file: /OpenBSD/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.173
diff -u -p -r1.173 bgpctl.c
--- usr.sbin/bgpctl/bgpctl.c13 Nov 2013 22:52:41 -  1.173
+++ usr.sbin/bgpctl/bgpctl.c3 Mar 2014 13:21:23 -
@@ -1346,7 +1346,6 @@ show_attr(void *b, u_int16_t len)
u_int16_talen, ioff;
u_int8_t flags, type;
 
-   data = b;
if (len  3)
errx(1, show_attr: too short bgp attr);
 
@@ -1362,7 +1361,7 @@ show_attr(void *b, u_int16_t len)
data += 4;
len -= 4;
} else {
-   alen = data[2];
+   alen = (u_char)data[2];
data += 3;
len -= 3;
}



thinkpad adaptive keyboard patch

2014-03-17 Thread rivo nurges
Hi!

New 2nd generation Lenovo X1 Carbon has touchable lcd strip instead
of the F1-12 keys and the multimedia keys. It has 5 modes with tons
of useless buttons triggering acpi hotkey events and 6th inactive
mode.

This patch adds support for switching between the Home and the
Function modes. The Function mode has the standard F1-12 buttons
and the Home mode has Volume, Mute and Brightness buttons. Other
functions of the the Home mode are ignored. On power up BIOS activates
the Function mode for us, on suspend it goes to the inactive mode
and we need to reenable it when coming from suspend.

The patch has been tested on X1 Carbon, X220 and X61s

Dmesg:
OpenBSD 5.5-current (GENERIC.MP) #26: Mon Mar 17 18:14:05 UTC 2014
rix@x1:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 8262828032 (7880MB)
avail mem = 8034148352 (7661MB)
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xdcd3d000 (60 entries)
bios0: vendor LENOVO version GRET32WW (1.09 ) date 02/13/2014
bios0: LENOVO 20A7005KMS
acpi0 at bios0: rev 2
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP SLIC ASF! DBGP ECDT HPET APIC MCFG SSDT SSDT SSDT SSDT 
SSDT SSDT TCPA UEFI MSDM BATB FPDT UEFI SSDT
acpi0: wakeup devices LID_(S4) SLPB(S3) IGBE(S4) EXP2(S4) XHCI(S3) EHC1(S3)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpiec0 at acpi0
acpihpet0 at acpi0: 14318179 Hz
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-4550U CPU @ 1.50GHz, 1396.98 MHz
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4, IBE
cpu1 at mainbus0: apid 1 (application processor)
cpu1: Intel(R) Core(TM) i7-4550U CPU @ 1.50GHz, 1396.77 MHz
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 1, core 0, package 0
cpu2 at mainbus0: apid 2 (application processor)
cpu2: Intel(R) Core(TM) i7-4550U CPU @ 1.50GHz, 1396.77 MHz
cpu2: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID
cpu2: 256KB 64b/line 8-way L2 cache
cpu2: smt 0, core 1, package 0
cpu3 at mainbus0: apid 3 (application processor)
cpu3: Intel(R) Core(TM) i7-4550U CPU @ 1.50GHz, 1396.77 MHz
cpu3: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID
cpu3: 256KB 64b/line 8-way L2 cache
cpu3: smt 1, core 1, package 0
ioapic0 at mainbus0: apid 2 pa 0xfec0, version 20, 40 pins
acpimcfg0 at acpi0 addr 0xf800, bus 0-63
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus -1 (PEG_)
acpiprt2 at acpi0: bus 2 (EXP1)
acpiprt3 at acpi0: bus 3 (EXP2)
acpiprt4 at acpi0: bus -1 (EXP3)
acpicpu0 at acpi0: C3, C1, PSS
acpicpu1 at acpi0: C3, C1, PSS
acpicpu2 at acpi0: C3, C1, PSS
acpicpu3 at acpi0: C3, C1, PSS
acpipwrres0 at acpi0: PUBS, resource for XHCI, EHC1
acpitz0 at acpi0: critical temperature is 200 degC
acpibtn0 at acpi0: LID_
acpibtn1 at acpi0: SLPB
acpibat0 at acpi0: BAT0 model 45N1701 serial 11637 type LiP oem SONY
acpibat1 at acpi0: BAT1 not present
acpiac0 at acpi0: AC unit online
acpithinkpad0 at acpi0
cpu0: Enhanced SpeedStep 1396 MHz: speeds: 2101, 2100, 2000, 1900, 1800, 1700, 
1600, 1500, 1400, 1300, 1200, 1100, 1000, 900, 800, 777 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 Intel Core 4G Host rev 0x09
vga1 at pci0 dev 2 function 0 Intel HD Graphics 5000 rev 0x09
intagp0 at vga1
agp0 at intagp0: aperture at 0xe000, size 0x1000
inteldrm0 at vga1
drm0 at inteldrm0
error: [drm:pid0:i915_write32] *ERROR* Unknown unclaimed register before 
writing to 10
error: [drm:pid0:intel_dp_set_link_train] *ERROR* Timed out waiting for DP idle 
patterns
error: [drm:pid0:i915_write32] *ERROR* Unknown unclaimed register before 
writing to 64040
inteldrm0: 

Re: Intel HD Graphics 4000, only one monitor detected

2014-02-14 Thread rivo nurges
On Fri, Feb 14, 2014 at 07:54:56PM +1100, Jonathan Gray wrote:

Hi!

 It would be interesting to see if compiling your own kernel
 sometime after the following commit by kettenis@ helps:

I have HD 3000 with the same issue. I just tested new kernel compiled
from sources with the mentioned commit included and its still not
working.

As a workaround, forcing AccelMethod to uxa works.

-- 
rix



Dell 5540 HSDPA

2011-10-20 Thread rivo nurges
Hi!

The diff below makes cdce(4) to recognize cdce part of my Dell 5540 mini-pcie
card.

cdce port must be enabled before use by sending following to one
of the serial ports(should it be somehow documented in the manpage?):

AT+CFUN=1 # enable radio
AT+CGDCONT=1,IP,internet # configure apn
AT*ENAP=1,1 # enable cdce port

umodem0 at uhub5 port 6 configuration 1 interface 1 ADell Wireless 5540 Dell 
Wireless 5540 rev 2.00/0.00 addr 3
umodem0: data interface 2, has CM over data, has break
umodem0: status change notification available
ucom0 at umodem0
umodem1 at uhub5 port 6 configuration 1 interface 3 ADell Wireless 5540 Dell 
Wireless 5540 rev 2.00/0.00 addr 3
umodem1: data interface 4, has CM over data, has break
umodem1: status change notification available
ucom1 at umodem1
cdce0 at uhub5 port 6 configuration 1 interface 6 ADell Wireless 5540 Dell 
Wireless 5540 rev 2.00/0.00 addr 3
cdce0: address 02:80:37:ec:02:00
umodem2 at uhub5 port 6 configuration 1 interface 9 ADell Wireless 5540 Dell 
Wireless 5540 rev 2.00/0.00 addr 3
umodem2: data interface 10, has CM over data, has break
umodem2: status change notification available
ucom2 at umodem2
ugen0 at uhub5 port 6 configuration 1 ADell Wireless 5540 Dell Wireless 5540 
rev 2.00/0.00 addr 3

Diff:

Index: sys/dev/usb/if_cdce.c
===
RCS file: /OpenBSD/src/sys/dev/usb/if_cdce.c,v
retrieving revision 1.50
diff -u -p -r1.50 if_cdce.c
--- sys/dev/usb/if_cdce.c   3 Jul 2011 15:47:17 -   1.50
+++ sys/dev/usb/if_cdce.c   20 Oct 2011 10:03:40 -
@@ -146,8 +146,9 @@ cdce_match(struct device *parent, void *
if (cdce_lookup(uaa-vendor, uaa-product) != NULL)
return (UMATCH_VENDOR_PRODUCT);
 
-   if (id-bInterfaceClass == UICLASS_CDC  id-bInterfaceSubClass ==
-   UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL)
+   if (id-bInterfaceClass == UICLASS_CDC  (
+   id-bInterfaceSubClass == 
UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL ||
+   id-bInterfaceSubClass == UISUBCLASS_MOBILE_DIRECT_LINE_MODEL))
return (UMATCH_IFACECLASS_GENERIC);
 
return (UMATCH_NONE);
Index: sys/dev/usb/usb.h
===
RCS file: /OpenBSD/src/sys/dev/usb/usb.h,v
retrieving revision 1.37
diff -u -p -r1.37 usb.h
--- sys/dev/usb/usb.h   4 Mar 2011 23:55:32 -   1.37
+++ sys/dev/usb/usb.h   20 Oct 2011 10:03:40 -
@@ -412,6 +412,7 @@ typedef struct {
 #define UISUBCLASS_CAPI_CONTROLMODEL   5
 #define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
 #define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
+#define UISUBCLASS_MOBILE_DIRECT_LINE_MODEL10
 #define   UIPROTO_CDC_AT   1
 
 #define UICLASS_HID0x03
Index: share/man/man4/cdce.4
===
RCS file: /OpenBSD/src/share/man/man4/cdce.4,v
retrieving revision 1.14
diff -u -p -r1.14 cdce.4
--- share/man/man4/cdce.4   14 Mar 2008 15:19:52 -  1.14
+++ share/man/man4/cdce.4   20 Oct 2011 10:03:40 -
@@ -46,6 +46,8 @@ including the following:
 .It
 Acer Labs USB 2.0 Data Link
 .It
+Dell Wireless 5540
+.It
 FRITZ!Box Fon ata 1020
 .It
 G.Mate YP3X00


-- 
rivo