Bug 206938 - Safari hangs indefinitely on connections that accept the TCP connection but do not then negotiation the TLS connection
Summary: Safari hangs indefinitely on connections that accept the TCP connection but d...
Status: RESOLVED MOVED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: Safari 13
Hardware: Mac macOS 10.15
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-01-29 09:01 PST by Andrew Howden
Modified: 2020-01-30 11:25 PST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Howden 2020-01-29 09:01:28 PST
Hola Crew, 

I hope this bug report finds you well!

At the time of writing it appears that Safari either does not or has an extremely long timeout with the TLS component of the connection. I believe it would be a nicer experience for users if the connection was closed earlier (perhaps 3 minutes or so), rather than continuing.

The steps to reproduce are as follows:

1. Alias a path to a common website (such as example.com) to 127.0.0.1 via /etc/hosts
2. Compile and run the golang script below
3. Attempt to connect to https://${WEBSITE}
4. Wait (so far I as can assess indefinitely)

It is difficult to assess the real world impact of this bug. It was discovered while investigating an intermittent (rarely occurring) similarly presenting issue accessing the following resource:

- https://img01.ztat.net/article/N1/24/1D/10/3E/11/N1241D103-E11@17.jpg?imwidth=300

We could not replicate it on the above resource consistently, however were able to replicate it by stubbing out the connection and sinkholing the TLS portion of the connection.

Is it possible to introduce a timeout for this (or perhaps the the entire) connection? In this way the error will be presented to users transparently.

Kind regards, 
Andrew.

—
package main

import (
	"log"
	"net"
)

func handle(c net.Conn) {
	b := make([]byte, 1024)
	log.Printf("connection accepted from %s ", c.RemoteAddr())

	for {
		_, err := c.Read(b)

		if err != nil {
			log.Printf("error: %s", err.Error())

			// We leave the connection open to mess with safari. All we want to do is just do one way traffic,
			// and pretend to be alive.
			return
		}

		log.Printf("%s", b)
	}
}

func main() {
	ln, err := net.Listen("tcp", ":443")
	if err != nil {
		panic(err)
	}

	for {
		c, err := ln.Accept()

		if err != nil {
			panic(err)
		}

		go handle(c)
	}
}
Comment 1 Alexey Proskuryakov 2020-01-29 18:05:25 PST
Thank you for the report! This is almost certainly an issue in Apple networking frameworks below WebKit. Could you please report it via https://feedbackassistant.apple.com/ to have a direct link to the team looking into this? Please post feedback ID here for reference.
Comment 2 Alexey Proskuryakov 2020-01-29 18:07:38 PST
A timeout for entire request separate from TCP timeout would be wrong I think. There are definitely web pages that take minutes to process a request, and to generate content.
Comment 3 Andrew Howden 2020-01-30 04:08:45 PST
Good Afternoon Alexey! 

> Could you please report it via https://feedbackassistant.apple.com/ to have a direct link to the team looking into this? Please post feedback ID here for reference

The feedback ID is FB7557362

> This is almost certainly an issue in Apple networking frameworks below WebKit.

That made sense, but I have since found some evidence it might be possible to address it higher in the stack.

In order to submit the feedback I needed to shift my iOS device into "beta", pull down the app and so fourth. The bug exists there also, however I was curious and tested chrome -- where the bug does not exist; Chrome times out after ~60 seconds with:

ERR_CONNECTION_TIMED_OUT

I had a quick look and haven't been able to to determine from where this error is generated (I'm neither browser nor C++ developer), but it hints that the behavior might be solvable.
Comment 4 Alexey Proskuryakov 2020-01-30 09:54:33 PST
Thank you! Marking as MOVED.

It wasn't clear from the original report that this was about iOS. Chrome definitely doesn't use this part of OS networking stack on macOS, and I think that they have their own on iOS too, but I'm not quite sure. We will look into this if networking engineers determine that this is a WebKit issue.
Comment 5 Alexey Proskuryakov 2020-01-30 10:00:42 PST
rdar://problem/59023439
Comment 6 Andrew Howden 2020-01-30 11:25:01 PST
Sorry I should clarify 😅 I reproduced it on both iOS Safari and safari on MacOS. 

Submitting the second report via iOS was just pragmatism; I had to borrow a Mac laptop to reproduce the bug initially, but have an iPhone available full time.

Cheers,