* [0.7.2] Start threads as background in HashedWheelTimer, LoopExecutor, ThreadDeathWatcher

* + code formatting

* [0.7.3] Target net5 and net6 (#2)

target net5 and net6
Adopted TlsHandler for the case when Handshake completion callback is dispatched asynchronously to thread pool
Introduced SingleThreadedEmbededChannel for TlsHandler and SniHandler tests

* + Update DotNetVersion to "6.0.302" in build.ps1
This commit is contained in:
Andrey Ilnitsky 2022-08-02 16:37:48 -07:00 коммит произвёл GitHub
Родитель 54fd364a93
Коммит f754c83069
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
104 изменённых файлов: 1674 добавлений и 479 удалений

Просмотреть файл

@ -111,180 +111,235 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Package|Any CPU = Package|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Release|Any CPU.Build.0 = Release|Any CPU
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Package|Any CPU.ActiveCfg = Package|Any CPU
{DF4FF0D0-A5CE-471F-B946-538C28C21CBB}.Package|Any CPU.Build.0 = Package|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Release|Any CPU.Build.0 = Release|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Package|Any CPU.ActiveCfg = Package|Any CPU
{64508DA2-40F1-4CC3-93E8-EA3B18A64E7E}.Package|Any CPU.Build.0 = Package|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Release|Any CPU.Build.0 = Release|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Package|Any CPU.ActiveCfg = Package|Any CPU
{82796E9E-1331-4858-90C3-8E74BA4CC383}.Package|Any CPU.Build.0 = Package|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Release|Any CPU.Build.0 = Release|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Package|Any CPU.ActiveCfg = Package|Any CPU
{25F7AD69-7836-46E8-9B29-0FBB3C128FFB}.Package|Any CPU.Build.0 = Package|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Release|Any CPU.Build.0 = Release|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Package|Any CPU.ActiveCfg = Package|Any CPU
{12DCCEFD-623B-46CC-979C-407FA265E239}.Package|Any CPU.Build.0 = Package|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Release|Any CPU.Build.0 = Release|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Package|Any CPU.ActiveCfg = Package|Any CPU
{5ADB0FF5-8EFC-475A-BF08-6B35EF728329}.Package|Any CPU.Build.0 = Package|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Release|Any CPU.Build.0 = Release|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Package|Any CPU.ActiveCfg = Package|Any CPU
{D284C2BF-E06E-481B-B301-503A9D477B0E}.Package|Any CPU.Build.0 = Package|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Release|Any CPU.Build.0 = Release|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Package|Any CPU.ActiveCfg = Package|Any CPU
{75A1BCC1-A7F3-4893-99C5-3235F87DB00E}.Package|Any CPU.Build.0 = Package|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Release|Any CPU.Build.0 = Release|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Package|Any CPU.ActiveCfg = Package|Any CPU
{1F442118-A665-4891-B056-FE9E54C5B049}.Package|Any CPU.Build.0 = Package|Any CPU
{572E1914-489F-402D-944F-71EE0632E5D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{572E1914-489F-402D-944F-71EE0632E5D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{572E1914-489F-402D-944F-71EE0632E5D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{572E1914-489F-402D-944F-71EE0632E5D8}.Release|Any CPU.Build.0 = Release|Any CPU
{572E1914-489F-402D-944F-71EE0632E5D8}.Package|Any CPU.ActiveCfg = Package|Any CPU
{DA54DBAF-CCDA-4AD1-9FF9-EB6F890D1091}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA54DBAF-CCDA-4AD1-9FF9-EB6F890D1091}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA54DBAF-CCDA-4AD1-9FF9-EB6F890D1091}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA54DBAF-CCDA-4AD1-9FF9-EB6F890D1091}.Release|Any CPU.Build.0 = Release|Any CPU
{DA54DBAF-CCDA-4AD1-9FF9-EB6F890D1091}.Package|Any CPU.ActiveCfg = Package|Any CPU
{72C92F76-F804-4300-BFF1-459420D9EF0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72C92F76-F804-4300-BFF1-459420D9EF0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72C92F76-F804-4300-BFF1-459420D9EF0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72C92F76-F804-4300-BFF1-459420D9EF0B}.Release|Any CPU.Build.0 = Release|Any CPU
{72C92F76-F804-4300-BFF1-459420D9EF0B}.Package|Any CPU.ActiveCfg = Package|Any CPU
{E31A5D46-71B7-4B7E-A9F8-3F011822F28A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E31A5D46-71B7-4B7E-A9F8-3F011822F28A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E31A5D46-71B7-4B7E-A9F8-3F011822F28A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E31A5D46-71B7-4B7E-A9F8-3F011822F28A}.Release|Any CPU.Build.0 = Release|Any CPU
{E31A5D46-71B7-4B7E-A9F8-3F011822F28A}.Package|Any CPU.ActiveCfg = Package|Any CPU
{3AF8A62F-F5CE-4C2D-B356-8B9FDFA51668}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AF8A62F-F5CE-4C2D-B356-8B9FDFA51668}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AF8A62F-F5CE-4C2D-B356-8B9FDFA51668}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3AF8A62F-F5CE-4C2D-B356-8B9FDFA51668}.Release|Any CPU.Build.0 = Release|Any CPU
{3AF8A62F-F5CE-4C2D-B356-8B9FDFA51668}.Package|Any CPU.ActiveCfg = Package|Any CPU
{A7FC497E-790A-4980-B57C-32AF4AD4AB9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7FC497E-790A-4980-B57C-32AF4AD4AB9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7FC497E-790A-4980-B57C-32AF4AD4AB9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7FC497E-790A-4980-B57C-32AF4AD4AB9D}.Release|Any CPU.Build.0 = Release|Any CPU
{A7FC497E-790A-4980-B57C-32AF4AD4AB9D}.Package|Any CPU.ActiveCfg = Package|Any CPU
{08C19033-23B2-47D7-8332-86273AE287BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08C19033-23B2-47D7-8332-86273AE287BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08C19033-23B2-47D7-8332-86273AE287BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08C19033-23B2-47D7-8332-86273AE287BC}.Release|Any CPU.Build.0 = Release|Any CPU
{08C19033-23B2-47D7-8332-86273AE287BC}.Package|Any CPU.ActiveCfg = Package|Any CPU
{CE97D2EC-3EA9-4FEC-B304-F57646DB54FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE97D2EC-3EA9-4FEC-B304-F57646DB54FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE97D2EC-3EA9-4FEC-B304-F57646DB54FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE97D2EC-3EA9-4FEC-B304-F57646DB54FD}.Release|Any CPU.Build.0 = Release|Any CPU
{CE97D2EC-3EA9-4FEC-B304-F57646DB54FD}.Package|Any CPU.ActiveCfg = Package|Any CPU
{D0DBB346-BDDA-4E28-A335-6D3E1F9902DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0DBB346-BDDA-4E28-A335-6D3E1F9902DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0DBB346-BDDA-4E28-A335-6D3E1F9902DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0DBB346-BDDA-4E28-A335-6D3E1F9902DF}.Release|Any CPU.Build.0 = Release|Any CPU
{D0DBB346-BDDA-4E28-A335-6D3E1F9902DF}.Package|Any CPU.ActiveCfg = Package|Any CPU
{5D5A3137-F118-4F6C-ABE7-2523184A3A2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D5A3137-F118-4F6C-ABE7-2523184A3A2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D5A3137-F118-4F6C-ABE7-2523184A3A2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D5A3137-F118-4F6C-ABE7-2523184A3A2D}.Release|Any CPU.Build.0 = Release|Any CPU
{5D5A3137-F118-4F6C-ABE7-2523184A3A2D}.Package|Any CPU.ActiveCfg = Package|Any CPU
{BDA099C5-E435-49DF-9922-58D63E11B764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDA099C5-E435-49DF-9922-58D63E11B764}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDA099C5-E435-49DF-9922-58D63E11B764}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDA099C5-E435-49DF-9922-58D63E11B764}.Release|Any CPU.Build.0 = Release|Any CPU
{BDA099C5-E435-49DF-9922-58D63E11B764}.Package|Any CPU.ActiveCfg = Package|Any CPU
{3DA49C12-3614-40F5-B5CE-8B95F872EFC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DA49C12-3614-40F5-B5CE-8B95F872EFC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DA49C12-3614-40F5-B5CE-8B95F872EFC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DA49C12-3614-40F5-B5CE-8B95F872EFC1}.Release|Any CPU.Build.0 = Release|Any CPU
{3DA49C12-3614-40F5-B5CE-8B95F872EFC1}.Package|Any CPU.ActiveCfg = Package|Any CPU
{9AE188E0-F328-4A88-AF5F-CE0C1D4D0036}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AE188E0-F328-4A88-AF5F-CE0C1D4D0036}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AE188E0-F328-4A88-AF5F-CE0C1D4D0036}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9AE188E0-F328-4A88-AF5F-CE0C1D4D0036}.Release|Any CPU.Build.0 = Release|Any CPU
{9AE188E0-F328-4A88-AF5F-CE0C1D4D0036}.Package|Any CPU.ActiveCfg = Package|Any CPU
{66491D47-2BFB-45CF-A582-C11860219512}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66491D47-2BFB-45CF-A582-C11860219512}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66491D47-2BFB-45CF-A582-C11860219512}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66491D47-2BFB-45CF-A582-C11860219512}.Release|Any CPU.Build.0 = Release|Any CPU
{66491D47-2BFB-45CF-A582-C11860219512}.Package|Any CPU.ActiveCfg = Package|Any CPU
{664ECD06-26EB-4F8F-8D88-5444A5E766E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{664ECD06-26EB-4F8F-8D88-5444A5E766E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{664ECD06-26EB-4F8F-8D88-5444A5E766E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{664ECD06-26EB-4F8F-8D88-5444A5E766E0}.Release|Any CPU.Build.0 = Release|Any CPU
{664ECD06-26EB-4F8F-8D88-5444A5E766E0}.Package|Any CPU.ActiveCfg = Package|Any CPU
{EAE5000B-9A97-4308-B791-0B71DE0A8219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAE5000B-9A97-4308-B791-0B71DE0A8219}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAE5000B-9A97-4308-B791-0B71DE0A8219}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAE5000B-9A97-4308-B791-0B71DE0A8219}.Release|Any CPU.Build.0 = Release|Any CPU
{EAE5000B-9A97-4308-B791-0B71DE0A8219}.Package|Any CPU.ActiveCfg = Package|Any CPU
{E854F61B-548A-4100-A766-35B972B9EE11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E854F61B-548A-4100-A766-35B972B9EE11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E854F61B-548A-4100-A766-35B972B9EE11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E854F61B-548A-4100-A766-35B972B9EE11}.Release|Any CPU.Build.0 = Release|Any CPU
{E854F61B-548A-4100-A766-35B972B9EE11}.Package|Any CPU.ActiveCfg = Package|Any CPU
{22C53CFB-B54A-438E-820F-42C94D557345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22C53CFB-B54A-438E-820F-42C94D557345}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22C53CFB-B54A-438E-820F-42C94D557345}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22C53CFB-B54A-438E-820F-42C94D557345}.Release|Any CPU.Build.0 = Release|Any CPU
{22C53CFB-B54A-438E-820F-42C94D557345}.Package|Any CPU.ActiveCfg = Package|Any CPU
{A4E85E94-383F-40EA-9478-0545070E52F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4E85E94-383F-40EA-9478-0545070E52F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4E85E94-383F-40EA-9478-0545070E52F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4E85E94-383F-40EA-9478-0545070E52F5}.Release|Any CPU.Build.0 = Release|Any CPU
{A4E85E94-383F-40EA-9478-0545070E52F5}.Package|Any CPU.ActiveCfg = Package|Any CPU
{928090A9-AAC7-496C-A8E3-D242D2D8BC74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{928090A9-AAC7-496C-A8E3-D242D2D8BC74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{928090A9-AAC7-496C-A8E3-D242D2D8BC74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{928090A9-AAC7-496C-A8E3-D242D2D8BC74}.Release|Any CPU.Build.0 = Release|Any CPU
{928090A9-AAC7-496C-A8E3-D242D2D8BC74}.Package|Any CPU.ActiveCfg = Package|Any CPU
{D69B9924-5C2E-41BC-9354-A12DA7D03FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D69B9924-5C2E-41BC-9354-A12DA7D03FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D69B9924-5C2E-41BC-9354-A12DA7D03FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D69B9924-5C2E-41BC-9354-A12DA7D03FDF}.Release|Any CPU.Build.0 = Release|Any CPU
{D69B9924-5C2E-41BC-9354-A12DA7D03FDF}.Package|Any CPU.ActiveCfg = Package|Any CPU
{ED307D87-E1BF-49B6-9591-5250D431C758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED307D87-E1BF-49B6-9591-5250D431C758}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED307D87-E1BF-49B6-9591-5250D431C758}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED307D87-E1BF-49B6-9591-5250D431C758}.Release|Any CPU.Build.0 = Release|Any CPU
{ED307D87-E1BF-49B6-9591-5250D431C758}.Package|Any CPU.ActiveCfg = Package|Any CPU
{0E4B622A-063B-4A39-87CF-F18AEACBDDC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E4B622A-063B-4A39-87CF-F18AEACBDDC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E4B622A-063B-4A39-87CF-F18AEACBDDC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E4B622A-063B-4A39-87CF-F18AEACBDDC5}.Release|Any CPU.Build.0 = Release|Any CPU
{0E4B622A-063B-4A39-87CF-F18AEACBDDC5}.Package|Any CPU.ActiveCfg = Package|Any CPU
{E2BEAAAE-497B-49F4-AD27-03BE20924311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2BEAAAE-497B-49F4-AD27-03BE20924311}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2BEAAAE-497B-49F4-AD27-03BE20924311}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2BEAAAE-497B-49F4-AD27-03BE20924311}.Release|Any CPU.Build.0 = Release|Any CPU
{E2BEAAAE-497B-49F4-AD27-03BE20924311}.Package|Any CPU.ActiveCfg = Package|Any CPU
{F2490822-51F7-4B65-8B21-EE0082B76745}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2490822-51F7-4B65-8B21-EE0082B76745}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2490822-51F7-4B65-8B21-EE0082B76745}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2490822-51F7-4B65-8B21-EE0082B76745}.Release|Any CPU.Build.0 = Release|Any CPU
{F2490822-51F7-4B65-8B21-EE0082B76745}.Package|Any CPU.ActiveCfg = Package|Any CPU
{07C97A77-61B6-4BB5-9436-3A7FC379B75E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07C97A77-61B6-4BB5-9436-3A7FC379B75E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07C97A77-61B6-4BB5-9436-3A7FC379B75E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07C97A77-61B6-4BB5-9436-3A7FC379B75E}.Release|Any CPU.Build.0 = Release|Any CPU
{07C97A77-61B6-4BB5-9436-3A7FC379B75E}.Package|Any CPU.ActiveCfg = Package|Any CPU
{7155D1E6-00CE-4081-B922-E6C5524EE600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7155D1E6-00CE-4081-B922-E6C5524EE600}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7155D1E6-00CE-4081-B922-E6C5524EE600}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7155D1E6-00CE-4081-B922-E6C5524EE600}.Release|Any CPU.Build.0 = Release|Any CPU
{7155D1E6-00CE-4081-B922-E6C5524EE600}.Package|Any CPU.ActiveCfg = Package|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Release|Any CPU.Build.0 = Release|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Package|Any CPU.ActiveCfg = Package|Any CPU
{9FE6A783-C20D-4097-9988-4178E2C4CE75}.Package|Any CPU.Build.0 = Package|Any CPU
{1012C962-7F6D-4EC5-A0EC-0741A95BAD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1012C962-7F6D-4EC5-A0EC-0741A95BAD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1012C962-7F6D-4EC5-A0EC-0741A95BAD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1012C962-7F6D-4EC5-A0EC-0741A95BAD6B}.Release|Any CPU.Build.0 = Release|Any CPU
{1012C962-7F6D-4EC5-A0EC-0741A95BAD6B}.Package|Any CPU.ActiveCfg = Package|Any CPU
{A7CACAE7-66E7-43DA-948B-28EB0DDDB582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7CACAE7-66E7-43DA-948B-28EB0DDDB582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7CACAE7-66E7-43DA-948B-28EB0DDDB582}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7CACAE7-66E7-43DA-948B-28EB0DDDB582}.Release|Any CPU.Build.0 = Release|Any CPU
{A7CACAE7-66E7-43DA-948B-28EB0DDDB582}.Package|Any CPU.ActiveCfg = Package|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Release|Any CPU.Build.0 = Release|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Package|Any CPU.ActiveCfg = Package|Any CPU
{5F68A5B1-7907-4B16-8AFE-326E9DD7D65B}.Package|Any CPU.Build.0 = Package|Any CPU
{16C89E7C-1575-4685-8DFA-8E7E2C6101BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16C89E7C-1575-4685-8DFA-8E7E2C6101BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16C89E7C-1575-4685-8DFA-8E7E2C6101BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16C89E7C-1575-4685-8DFA-8E7E2C6101BF}.Release|Any CPU.Build.0 = Release|Any CPU
{16C89E7C-1575-4685-8DFA-8E7E2C6101BF}.Package|Any CPU.ActiveCfg = Package|Any CPU
{EA387B4B-DAD0-4E34-B8A3-79EA4616726A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EA387B4B-DAD0-4E34-B8A3-79EA4616726A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA387B4B-DAD0-4E34-B8A3-79EA4616726A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA387B4B-DAD0-4E34-B8A3-79EA4616726A}.Release|Any CPU.Build.0 = Release|Any CPU
{EA387B4B-DAD0-4E34-B8A3-79EA4616726A}.Package|Any CPU.ActiveCfg = Package|Any CPU
{3326DB6E-023E-483F-9A1C-5905D3091B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3326DB6E-023E-483F-9A1C-5905D3091B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3326DB6E-023E-483F-9A1C-5905D3091B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3326DB6E-023E-483F-9A1C-5905D3091B57}.Release|Any CPU.Build.0 = Release|Any CPU
{3326DB6E-023E-483F-9A1C-5905D3091B57}.Package|Any CPU.ActiveCfg = Package|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -1,3 +1,8 @@
#### 0.7.3 July 28, 2022
- target net5 and net6
- Adopted TlsHandler for the case when Handshake completion callback is dispatched asynchronously to thread pool
- Introduced SingleThreadedEmbededChannel for TlsHandler and SniHandler tests
#### 0.7.2 February 14, 2022
- Start threads as background in HashedWheelTimer, LoopExecutor, ThreadDeathWatcher
- Google.Protobuf 3.19.4 (latest)

Просмотреть файл

@ -33,7 +33,7 @@ Param(
$CakeVersion = "0.27.1"
$DotNetChannel = "Current";
$DotNetVersion = "3.1.411";
$DotNetVersion = "6.0.302";
$DotNetInstallerUri = "https://dot.net/v1/dotnet-install.ps1";
$NugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
# Temporarily skip verification of addins.

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -22,7 +22,7 @@ namespace Examples.Common
{
get
{
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
return AppContext.BaseDirectory;
#else
return AppDomain.CurrentDomain.BaseDirectory;

Просмотреть файл

@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetty.Common\DotNetty.Common.csproj" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<ServerGarbageCollection>true</ServerGarbageCollection>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -11,6 +11,7 @@ namespace WebSockets.Client
using DotNetty.Common.Concurrency;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class WebSocketClientHandler : SimpleChannelInboundHandler<object>
{

Просмотреть файл

@ -2,9 +2,11 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -2,10 +2,12 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">2.0.3</NetStandardImplicitPackageVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<ServerGarbageCollection>true</ServerGarbageCollection>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

23
src/Directory.Build.props Normal file
Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Build Settings -->
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<DebugType Condition="'$(Configuration)'=='Release'">pdbonly</DebugType>
<DebugSymbols>True</DebugSymbols>
<Deterministic>true</Deterministic>
<!-- Package Settings -->
<DebugType Condition="'$(Configuration)'=='Package'">pdbonly</DebugType>
<Optimize Condition="'$(Configuration)'=='Package'">true</Optimize>
<PackageOutputPath>$(SolutionDir)build_output\packages</PackageOutputPath>
<GeneratePackageOnBuild Condition="'$(Configuration)'=='Package'">True</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<PackageVersion>0.7.3</PackageVersion>
<Version>$(PackageVersion)</Version>
</PropertyGroup>
</Project>

Просмотреть файл

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<Description>Buffer management in DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: buffer management</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>

Просмотреть файл

@ -386,7 +386,7 @@ namespace DotNetty.Buffers
internal static string GetString(byte* src, int length, Encoding encoding)
{
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
return encoding.GetString(src, length);
#else
int charCount = encoding.GetCharCount(src, length);

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs.Http</PackageId>
<Description>Http codec for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: Http codec</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

Просмотреть файл

@ -11,6 +11,7 @@ namespace DotNetty.Codecs.Http.WebSockets
using DotNetty.Common.Concurrency;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public abstract class WebSocketClientHandshaker
{

Просмотреть файл

@ -15,6 +15,7 @@ namespace DotNetty.Codecs.Http.WebSockets
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public abstract class WebSocketServerHandshaker
{

Просмотреть файл

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs.Mqtt</PackageId>
<Description>MQTT codec for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: MQTT codec</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs.Protobuf</PackageId>
<Description>Protobuf Proto3 codec for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: Protobuf Proto3 codec</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs.ProtocolBuffers</PackageId>
<Description>ProtocolBuffers Proto2 codec for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: ProtocolBuffers Proto2 codec</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs.Redis</PackageId>
<Description>Redis codec for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: Redis codec</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Codecs</PackageId>
<Description>General purpose codecs for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: codecs</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Common</PackageId>
<Description>DotNetty common routines</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: common routines</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>

Просмотреть файл

@ -15,6 +15,7 @@ namespace DotNetty.Common.Utilities
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal;
using DotNetty.Common.Internal.Logging;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public sealed class HashedWheelTimer : ITimer
{

Просмотреть файл

@ -6,6 +6,7 @@ namespace DotNetty.Common.Utilities
using System;
using System.Threading.Tasks;
using DotNetty.Common.Concurrency;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public static class TaskEx
{

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Handlers</PackageId>
<Description>Application handlers for DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: handlers</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -11,6 +11,7 @@ namespace DotNetty.Handlers.Streams
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class ChunkedWriteHandler<T> : ChannelDuplexHandler
{

Просмотреть файл

@ -214,7 +214,7 @@ namespace DotNetty.Handlers.Tls
};
hostname = idn.GetAscii(hostname);
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
// TODO: netcore does not have culture sensitive tolower()
hostname = hostname.ToLowerInvariant();
#else

Просмотреть файл

@ -0,0 +1,302 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if NET5_0_OR_GREATER
namespace DotNetty.Handlers.Tls
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
partial class TlsHandler
{
sealed class MediationStreamNet : MediationStreamBase
{
readonly CompositeSource source = new();
TaskCompletionSource<int> readCompletionSource;
Memory<byte> sslOwnedMemory;
int readByteCount;
public MediationStreamNet(TlsHandler owner)
: base(owner)
{
}
public override bool SourceIsReadable => this.source.IsReadable;
public override int SourceReadableBytes => this.source.GetTotalReadableBytes();
public override void SetSource(byte[] source, int offset) => this.source.AddSource(source, offset);
public override void ResetSource() => this.source.ResetSources();
public override void ExpandSource(int count)
{
this.source.Expand(count);
Memory<byte> sslMemory = this.sslOwnedMemory;
if (sslMemory.IsEmpty)
{
return;
}
this.sslOwnedMemory = default;
this.readByteCount = this.ReadFromInput(sslMemory);
// hack: this tricks SslStream's continuation to run synchronously instead of dispatching to TP. Remove once Begin/EndRead are available.
new Task(
ms =>
{
var self = (MediationStreamNet)ms;
TaskCompletionSource<int> p = self.readCompletionSource;
self.readCompletionSource = null;
p.TrySetResult(self.readByteCount);
},
this)
.RunSynchronously(TaskScheduler.Default);
}
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
=> this.owner.capturedContext.Executor.InEventLoop
? this.InLoopReadAsync(buffer, cancellationToken)
: new ValueTask<int>(this.OutOfLoopReadAsync(buffer, cancellationToken));
ValueTask<int> InLoopReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
if (this.SourceIsReadable)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer);
return new ValueTask<int>(read);
}
Contract.Assert(this.sslOwnedMemory.IsEmpty);
// take note of buffer - we will pass bytes there once available
this.sslOwnedMemory = buffer;
this.readCompletionSource = new TaskCompletionSource<int>();
return new ValueTask<int>(this.readCompletionSource.Task);
}
Task<int> OutOfLoopReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
return this.owner.capturedContext.Executor.SubmitAsync(
() =>
{
if (this.SourceIsReadable)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer);
return Task.FromResult(read);
}
Contract.Assert(this.sslOwnedMemory.IsEmpty);
// take note of buffer - we will pass bytes there once available
this.sslOwnedMemory = buffer;
this.readCompletionSource = new TaskCompletionSource<int>();
return this.readCompletionSource.Task;
},
cancellationToken).Unwrap();
}
public override void Write(byte[] buffer, int offset, int count)
{
if (this.owner.capturedContext.Executor.InEventLoop)
{
this.owner.FinishWrap(buffer, offset, count);
}
else
{
this.owner.capturedContext.Executor.Execute(() => this.owner.FinishWrap(buffer, offset, count));
}
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (this.owner.capturedContext.Executor.InEventLoop)
{
return this.owner.FinishWrapNonAppDataAsync(buffer, offset, count);
}
return this.owner.capturedContext.Executor.SubmitAsync(
() => this.owner.FinishWrapNonAppDataAsync(buffer, offset, count),
cancellationToken
).Unwrap();
}
public override void Flush()
{
// NOOP: called on SslStream.Close
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
TaskCompletionSource<int> p = this.readCompletionSource;
if (p != null)
{
this.readCompletionSource = null;
p.TrySetResult(0);
}
}
}
int ReadFromInput(Memory<byte> destination) => this.source.Read(destination);
#region Source
sealed class Source
{
byte[] input;
int startOffset;
int offset;
int length;
bool retained;
public Source(byte[] input, int offset)
{
this.input = input;
this.startOffset = offset;
this.offset = 0;
this.length = 0;
}
public int ReadableBytes => this.length - this.offset;
public bool IsReadable => this.ReadableBytes > 0;
public void Expand(int count)
{
Contract.Assert(!this.retained); // Retained source is not expected to be Expanded
this.length += count;
Contract.Assert(this.length <= this.input.Length);
}
public int Read(Memory<byte> destination)
{
int len = Math.Min(this.ReadableBytes, destination.Length);
new ReadOnlySpan<byte>(this.input, this.startOffset + this.offset, len).CopyTo(destination.Span);
this.offset += len;
return len;
}
// This is to avoid input bytes to be discarded by ref counting mechanism
public void Retain()
{
int readableBytes = this.ReadableBytes;
if (this.retained || readableBytes <= 0)
{
return;
}
// todo: is there a way to not discard those bytes till they are read??? If not, then use context.Allocator???
// Copy only readable bytes to a new buffer
byte[] copy = new byte[readableBytes];
Buffer.BlockCopy(this.input, this.startOffset + this.offset, copy, 0, readableBytes);
this.input = copy;
// Set both offsets to 0 and length to readableBytes (so that this.ReadableBytes stays the same)
this.startOffset = 0;
this.offset = 0;
this.length = readableBytes;
this.retained = true;
}
}
sealed class CompositeSource
{
// Why not List?
// 1. It's unlikely this list to grow more than 10 nodes. In fact in most cases it'll have one element only
// 2. Cleanup removes from head, so it's cheaper compared to List which shifts elements in this case.
readonly LinkedList<Source> sources = new LinkedList<Source>();
public bool IsReadable
{
get
{
// The composite source is readable if any readable sources, so
// it's enough to check on last one as we always AddLast
LinkedListNode<Source> last = this.sources.Last;
return last != null && last.Value.IsReadable;
}
}
public void AddSource(byte[] input, int offset)
{
// Always add to the tail
this.sources.AddLast(new Source(input, offset));
}
public void Expand(int count)
{
Contract.Assert(this.sources.Last != null); // AddSource is always called before
// Always expand the last added source
this.sources.Last.Value.Expand(count);
}
public int GetTotalReadableBytes()
{
int count = 0;
LinkedListNode<Source> node = this.sources.First;
while (node != null)
{
count += node.Value.ReadableBytes;
node = node.Next;
}
return count;
}
// Read from all readable sources to the destination starting from head (oldest)
public int Read(Memory<byte> destination)
{
int totalRead = 0;
LinkedListNode<Source> node = this.sources.First;
while (node != null && totalRead < destination.Length)
{
Source source = node.Value;
int read = source.Read(destination.Slice(totalRead, destination.Length - totalRead));
totalRead += read;
if (!source.IsReadable)
{
node = node.Next;
// Do not remove the node here as it can be expanded. Instead,
// remove in the CleanUp method below
}
}
return totalRead;
}
// Remove all not readable sources and retain readable. Start from first as it's the oldest
public void ResetSources()
{
LinkedListNode<Source> node = this.sources.First;
while (node != null)
{
if (!node.Value.IsReadable)
{
this.sources.RemoveFirst();
node = this.sources.First;
}
else
{
node.Value.Retain();
node = node.Next;
}
}
}
}
#endregion
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,338 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Handlers.Tls
{
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
partial class TlsHandler
{
sealed class MediationStream : MediationStreamBase
{
byte[] input;
int inputStartOffset;
int inputOffset;
int inputLength;
TaskCompletionSource<int> readCompletionSource;
ArraySegment<byte> sslOwnedBuffer;
#if NETSTANDARD2_0 || NETCOREAPP3_1
int readByteCount;
#else
SynchronousAsyncResult<int> syncReadResult;
AsyncCallback readCallback;
TaskCompletionSource writeCompletion;
AsyncCallback writeCallback;
#endif
public MediationStream(TlsHandler owner)
: base(owner)
{
}
public override int SourceReadableBytes => this.inputLength - this.inputOffset;
public override bool SourceIsReadable => this.SourceReadableBytes > 0;
public override void SetSource(byte[] source, int offset)
{
this.input = source;
this.inputStartOffset = offset;
this.inputOffset = 0;
this.inputLength = 0;
}
public override void ResetSource()
{
this.input = null;
this.inputLength = 0;
this.inputOffset = 0;
}
public override void ExpandSource(int count)
{
Contract.Assert(this.input != null);
this.inputLength += count;
ArraySegment<byte> sslBuffer = this.sslOwnedBuffer;
if (sslBuffer.Array == null)
{
// there is no pending read operation - keep for future
return;
}
this.sslOwnedBuffer = default(ArraySegment<byte>);
#if NETSTANDARD2_0 || NETCOREAPP3_1
this.readByteCount = this.ReadFromInput(sslBuffer.Array, sslBuffer.Offset, sslBuffer.Count);
// hack: this tricks SslStream's continuation to run synchronously instead of dispatching to TP. Remove once Begin/EndRead are available.
new Task(
ms =>
{
var self = (MediationStream)ms;
TaskCompletionSource<int> p = self.readCompletionSource;
self.readCompletionSource = null;
p.TrySetResult(self.readByteCount);
},
this)
.RunSynchronously(TaskScheduler.Default);
#else
int read = this.ReadFromInput(sslBuffer.Array, sslBuffer.Offset, sslBuffer.Count);
TaskCompletionSource<int> promise = this.readCompletionSource;
this.readCompletionSource = null;
promise.TrySetResult(read);
AsyncCallback callback = this.readCallback;
this.readCallback = null;
callback?.Invoke(promise.Task);
#endif
}
#if NETSTANDARD2_0 || NETCOREAPP3_1
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (this.SourceReadableBytes > 0)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer, offset, count);
return Task.FromResult(read);
}
Contract.Assert(this.sslOwnedBuffer.Array == null);
// take note of buffer - we will pass bytes there once available
this.sslOwnedBuffer = new ArraySegment<byte>(buffer, offset, count);
this.readCompletionSource = new TaskCompletionSource<int>();
return this.readCompletionSource.Task;
}
#else
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (this.SourceReadableBytes > 0)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer, offset, count);
var res = this.PrepareSyncReadResult(read, state);
callback?.Invoke(res);
return res;
}
Contract.Assert(this.sslOwnedBuffer.Array == null);
// take note of buffer - we will pass bytes there once available
this.sslOwnedBuffer = new ArraySegment<byte>(buffer, offset, count);
this.readCompletionSource = new TaskCompletionSource<int>(state);
this.readCallback = callback;
return this.readCompletionSource.Task;
}
public override int EndRead(IAsyncResult asyncResult)
{
SynchronousAsyncResult<int> syncResult = this.syncReadResult;
if (ReferenceEquals(asyncResult, syncResult))
{
return syncResult.Result;
}
Debug.Assert(this.readCompletionSource == null || this.readCompletionSource.Task == asyncResult);
Contract.Assert(!((Task<int>)asyncResult).IsCanceled);
try
{
return ((Task<int>)asyncResult).Result;
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw; // unreachable
}
}
IAsyncResult PrepareSyncReadResult(int readBytes, object state)
{
// it is safe to reuse sync result object as it can't lead to leak (no way to attach to it via handle)
SynchronousAsyncResult<int> result = this.syncReadResult ?? (this.syncReadResult = new SynchronousAsyncResult<int>());
result.Result = readBytes;
result.AsyncState = state;
return result;
}
#endif
public override void Write(byte[] buffer, int offset, int count) => this.owner.FinishWrap(buffer, offset, count);
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> this.owner.FinishWrapNonAppDataAsync(buffer, offset, count);
#if !(NETSTANDARD2_0 || NETCOREAPP3_1)
static readonly Action<Task, object> WriteCompleteCallback = HandleChannelWriteComplete;
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
Task task = this.WriteAsync(buffer, offset, count);
switch (task.Status)
{
case TaskStatus.RanToCompletion:
// write+flush completed synchronously (and successfully)
var result = new SynchronousAsyncResult<int>();
result.AsyncState = state;
callback?.Invoke(result);
return result;
default:
if (callback != null || state != task.AsyncState)
{
Contract.Assert(this.writeCompletion == null);
this.writeCallback = callback;
var tcs = new TaskCompletionSource(state);
this.writeCompletion = tcs;
task.ContinueWith(WriteCompleteCallback, this, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
else
{
return task;
}
}
}
static void HandleChannelWriteComplete(Task writeTask, object state)
{
var self = (MediationStream)state;
AsyncCallback callback = self.writeCallback;
self.writeCallback = null;
var promise = self.writeCompletion;
self.writeCompletion = null;
switch (writeTask.Status)
{
case TaskStatus.RanToCompletion:
promise.TryComplete();
break;
case TaskStatus.Canceled:
promise.TrySetCanceled();
break;
case TaskStatus.Faulted:
promise.TrySetException(writeTask.Exception);
break;
default:
throw new ArgumentOutOfRangeException("Unexpected task status: " + writeTask.Status);
}
callback?.Invoke(promise.Task);
}
public override void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult is SynchronousAsyncResult<int>)
{
return;
}
try
{
((Task)asyncResult).Wait();
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw;
}
}
#endif
int ReadFromInput(byte[] destination, int destinationOffset, int destinationCapacity)
{
Contract.Assert(destination != null);
byte[] source = this.input;
int readableBytes = this.SourceReadableBytes;
int length = Math.Min(readableBytes, destinationCapacity);
Buffer.BlockCopy(source, this.inputStartOffset + this.inputOffset, destination, destinationOffset, length);
this.inputOffset += length;
return length;
}
public override void Flush()
{
// NOOP: called on SslStream.Close
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
TaskCompletionSource<int> p = this.readCompletionSource;
if (p != null)
{
this.readCompletionSource = null;
p.TrySetResult(0);
}
}
}
#region plumbing
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
#endregion
#region sync result
sealed class SynchronousAsyncResult<T> : IAsyncResult
{
public T Result { get; set; }
public bool IsCompleted => true;
public WaitHandle AsyncWaitHandle
{
get { throw new InvalidOperationException("Cannot wait on a synchronous result."); }
}
public object AsyncState { get; set; }
public bool CompletedSynchronously => true;
}
#endregion
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Handlers.Tls
{
using System;
using System.IO;
partial class TlsHandler
{
abstract class MediationStreamBase : Stream
{
protected readonly TlsHandler owner;
public MediationStreamBase(TlsHandler owner)
{
this.owner = owner;
}
public static MediationStreamBase Create(TlsHandler owner)
{
#if NET5_0_OR_GREATER
return new TlsHandler.MediationStreamNet(owner);
#else
return new MediationStream(owner);
#endif
}
public abstract bool SourceIsReadable { get; }
public abstract int SourceReadableBytes { get; }
public abstract void SetSource(byte[] source, int offset);
public abstract void ExpandSource(int count);
public abstract void ResetSource();
#region plumbing
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
#endregion
}
}
}

Просмотреть файл

@ -5,21 +5,19 @@ namespace DotNetty.Handlers.Tls
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Net.Security;
using System.Runtime.ExceptionServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Common.Concurrency;
using DotNetty.Common;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public sealed class TlsHandler : ByteToMessageDecoder
public sealed partial class TlsHandler : ByteToMessageDecoder
{
readonly TlsSettings settings;
const int FallbackReadBufferSize = 256;
@ -29,11 +27,12 @@ namespace DotNetty.Handlers.Tls
static readonly Action<Task, object> HandshakeCompletionCallback = new Action<Task, object>(HandleHandshakeCompleted);
readonly SslStream sslStream;
readonly MediationStream mediationStream;
readonly MediationStreamBase mediationStream;
readonly TaskCompletionSource closeFuture;
TlsHandlerState state;
int packetLength;
(int packetLength, byte packetContentType) packetInfo;
List<(int packetLength, byte packetContentType)> pendingDataPackets;
volatile IChannelHandlerContext capturedContext;
BatchingPendingWriteQueue pendingUnencryptedWrites;
Task lastContextWriteTask;
@ -53,7 +52,7 @@ namespace DotNetty.Handlers.Tls
this.settings = settings;
this.closeFuture = new TaskCompletionSource();
this.mediationStream = new MediationStream(this);
this.mediationStream = MediationStreamBase.Create(this);
this.sslStream = sslStreamFactory(this.mediationStream);
}
@ -118,38 +117,74 @@ namespace DotNetty.Handlers.Tls
static void HandleHandshakeCompleted(Task task, object state)
{
var self = (TlsHandler)state;
if (self.capturedContext.Executor.InEventLoop)
{
HandleHandshakeCompletedInternal(task, self);
}
else
{
self.capturedContext.Executor.Execute(() => HandleHandshakeCompletedInternal(task, self));
}
}
static void HandleHandshakeCompletedInternal(Task task, TlsHandler self)
{
switch (task.Status)
{
case TaskStatus.RanToCompletion:
{
TlsHandlerState oldState = self.state;
Contract.Assert(!oldState.HasAny(TlsHandlerState.AuthenticationCompleted));
self.state = (oldState | TlsHandlerState.Authenticated) & ~(TlsHandlerState.Authenticating | TlsHandlerState.FlushedBeforeHandshake);
self.capturedContext.FireUserEventTriggered(TlsHandshakeCompletionEvent.Success);
// Due to possible async execution of HandleHandshakeCompleted continuation, we need to
// Unwrap any pending app data packets in case, when read completed and no more messages in the channel.
if (self.pendingDataPackets != null && self.pendingDataPackets.Count > 0)
{
TlsHandlerState oldState = self.state;
Contract.Assert(!oldState.HasAny(TlsHandlerState.AuthenticationCompleted));
self.state = (oldState | TlsHandlerState.Authenticated) & ~(TlsHandlerState.Authenticating | TlsHandlerState.FlushedBeforeHandshake);
self.capturedContext.FireUserEventTriggered(TlsHandshakeCompletionEvent.Success);
if (oldState.Has(TlsHandlerState.ReadRequestedBeforeAuthenticated) && !self.capturedContext.Channel.Configuration.AutoRead)
ThreadLocalObjectList output = ThreadLocalObjectList.NewInstance();
try
{
self.capturedContext.Read();
self.Unwrap(self.capturedContext, Unpooled.Empty, 0, 0, new List<(int packetLength, byte packetContentType)>(0), output);
for (int i = 0; i < output.Count; i++)
{
self.capturedContext.FireChannelRead(output[i]);
}
}
if (oldState.Has(TlsHandlerState.FlushedBeforeHandshake))
catch (Exception ex)
{
self.Wrap(self.capturedContext);
self.capturedContext.Flush();
throw new DecoderException(ex);
}
finally
{
output.Return();
}
break;
}
if (oldState.Has(TlsHandlerState.ReadRequestedBeforeAuthenticated) && !self.capturedContext.Channel.Configuration.AutoRead)
{
self.capturedContext.Read();
}
if (oldState.Has(TlsHandlerState.FlushedBeforeHandshake))
{
self.Wrap(self.capturedContext);
self.capturedContext.Flush();
}
break;
}
case TaskStatus.Canceled:
case TaskStatus.Faulted:
{
// ReSharper disable once AssignNullToNotNullAttribute -- task.Exception will be present as task is faulted
TlsHandlerState oldState = self.state;
Contract.Assert(!oldState.HasAny(TlsHandlerState.Authenticated));
self.HandleFailure(task.Exception);
break;
}
{
// ReSharper disable once AssignNullToNotNullAttribute -- task.Exception will be present as task is faulted
TlsHandlerState oldState = self.state;
Contract.Assert(!oldState.HasAny(TlsHandlerState.Authenticated));
self.HandleFailure(task.Exception);
break;
}
default:
throw new ArgumentOutOfRangeException(nameof(task), "Unexpected task status: " + task.Status);
}
@ -183,27 +218,27 @@ namespace DotNetty.Handlers.Tls
int offset = startOffset;
int totalLength = 0;
List<int> packetLengths;
List<(int, byte)> packetInfos;
// if we calculated the length of the current SSL record before, use that information.
if (this.packetLength > 0)
if (this.packetInfo.packetLength > 0)
{
if (endOffset - startOffset < this.packetLength)
if (endOffset - startOffset < this.packetInfo.packetLength)
{
// input does not contain a single complete SSL record
return;
}
else
{
packetLengths = new List<int>(4);
packetLengths.Add(this.packetLength);
offset += this.packetLength;
totalLength = this.packetLength;
this.packetLength = 0;
packetInfos = new List<(int, byte)>(4);
packetInfos.Add(this.packetInfo);
offset += this.packetInfo.packetLength;
totalLength = this.packetInfo.packetLength;
this.packetInfo = default;
}
}
else
{
packetLengths = new List<int>(4);
packetInfos = new List<(int, byte)>(4);
}
bool nonSslRecord = false;
@ -216,7 +251,7 @@ namespace DotNetty.Handlers.Tls
break;
}
int encryptedPacketLength = TlsUtils.GetEncryptedPacketLength(input, offset);
int encryptedPacketLength = TlsUtils.GetEncryptedPacketLength(input, offset, out byte contentType);
if (encryptedPacketLength == -1)
{
nonSslRecord = true;
@ -228,7 +263,7 @@ namespace DotNetty.Handlers.Tls
if (encryptedPacketLength > readableBytes)
{
// wait until the whole packet can be read
this.packetLength = encryptedPacketLength;
this.packetInfo = (encryptedPacketLength, contentType);
break;
}
@ -244,7 +279,7 @@ namespace DotNetty.Handlers.Tls
// We have a whole packet.
// Increment the offset to handle the next packet.
packetLengths.Add(encryptedPacketLength);
packetInfos.Add((encryptedPacketLength, contentType));
offset += encryptedPacketLength;
totalLength = newTotalLength;
}
@ -263,7 +298,7 @@ namespace DotNetty.Handlers.Tls
// See https://github.com/netty/netty/issues/1534
input.SkipBytes(totalLength);
this.Unwrap(context, input, startOffset, totalLength, packetLengths, output);
this.Unwrap(context, input, startOffset, totalLength, packetInfos, output);
if (!this.firedChannelRead)
{
@ -305,11 +340,18 @@ namespace DotNetty.Handlers.Tls
ctx.Read();
}
}
/// <summary>Unwraps inbound SSL records.</summary>
void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length, List<int> packetLengths, List<object> output)
void Unwrap(
IChannelHandlerContext ctx,
IByteBuffer packet,
int offset,
int length,
List<(int packetLength, byte packetContentType)> packetInfos,
List<object> output)
{
Contract.Requires(packetLengths.Count > 0);
Contract.Requires(packetInfos.Count > 0 || this.pendingDataPackets != null);
//bool notifyClosure = false; // todo: netty/issues/137
bool pending = false;
@ -318,17 +360,30 @@ namespace DotNetty.Handlers.Tls
try
{
ArraySegment<byte> inputIoBuffer = packet.GetIoBuffer(offset, length);
this.mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset);
int packetIndex = 0;
while (!this.EnsureAuthenticated())
if (packetInfos.Count > 0)
{
this.mediationStream.ExpandSource(packetLengths[packetIndex]);
if (++packetIndex == packetLengths.Count)
ArraySegment<byte> inputIoBuffer = packet.GetIoBuffer(offset, length);
this.mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset);
while (!this.EnsureAuthenticated())
{
return;
(int packetLength, byte type) = packetInfos[packetIndex];
this.mediationStream.ExpandSource(packetLength);
if (type == TlsUtils.SSL_CONTENT_TYPE_APPLICATION_DATA)
{
// Due to SslStream's implementation, it's possible that we expand after handshake completed. Hence, we
// need to make sure we call ReadFromSslStreamAsync for these packets later
this.pendingDataPackets = this.pendingDataPackets ?? new List<(int packetLength, byte packetContentType)>(8);
this.pendingDataPackets.Add((packetLength, type));
}
if (++packetIndex == packetInfos.Count)
{
return;
}
}
}
@ -353,10 +408,33 @@ namespace DotNetty.Handlers.Tls
}
// go through packets one by one (because SslStream does not consume more than 1 packet at a time)
for (; packetIndex < packetLengths.Count; packetIndex++)
// account pendingDataPackets
int skipExpandPacketCount = 0;
if (this.pendingDataPackets != null)
{
int currentPacketLength = packetLengths[packetIndex];
this.mediationStream.ExpandSource(currentPacketLength);
// We already expanded the source for all pendingDataPackets, so skip expand further below
skipExpandPacketCount = this.pendingDataPackets.Count;
// add packetLengths to pending except already processed
for (int i = packetIndex; i < packetInfos.Count; i++)
{
this.pendingDataPackets.Add(packetInfos[i]);
}
packetInfos = this.pendingDataPackets;
this.pendingDataPackets = null;
packetIndex = 0;
}
for (; packetIndex < packetInfos.Count; packetIndex++)
{
int currentPacketLength = packetInfos[packetIndex].packetLength;
if (--skipExpandPacketCount < 0)
{
// For pending packets we already expended, so skip expand
this.mediationStream.ExpandSource(currentPacketLength);
}
if (currentReadFuture != null)
{
@ -365,12 +443,10 @@ namespace DotNetty.Handlers.Tls
if (!currentReadFuture.IsCompleted)
{
// we did feed the whole current packet to SslStream yet it did not produce any result -> move to the next packet in input
continue;
}
int read = currentReadFuture.Result;
if (read == 0)
{
//Stream closed
@ -382,7 +458,7 @@ namespace DotNetty.Handlers.Tls
currentReadFuture = null;
outputBuffer = null;
if (this.mediationStream.SourceReadableBytes == 0)
if (!this.mediationStream.SourceIsReadable)
{
// we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there
@ -428,9 +504,11 @@ namespace DotNetty.Handlers.Tls
{
break;
}
int read = currentReadFuture.Result;
AddBufferToOutput(outputBuffer, read, output);
}
outputBuffer = ctx.Allocator.Buffer(FallbackReadBufferSize);
currentReadFuture = this.ReadFromSslStreamAsync(outputBuffer, FallbackReadBufferSize);
}
@ -514,6 +592,7 @@ namespace DotNetty.Handlers.Tls
{
return TaskEx.FromException(new UnsupportedMessageTypeException(message, typeof(IByteBuffer)));
}
return this.pendingUnencryptedWrites.Add(message);
}
@ -569,6 +648,7 @@ namespace DotNetty.Handlers.Tls
buffer.Release();
}
}
buf.ReadBytes(this.sslStream, buf.ReadableBytes); // this leads to FinishWrap being called 0+ times
buf.Release();
@ -627,7 +707,6 @@ namespace DotNetty.Handlers.Tls
{
// Release all resources such as internal buffers that SSLEngine
// is managing.
this.mediationStream.Dispose();
try
{
@ -664,323 +743,6 @@ namespace DotNetty.Handlers.Tls
this.CloseAsync(this.capturedContext);
}
}
sealed class MediationStream : Stream
{
readonly TlsHandler owner;
byte[] input;
int inputStartOffset;
int inputOffset;
int inputLength;
TaskCompletionSource<int> readCompletionSource;
ArraySegment<byte> sslOwnedBuffer;
#if NETSTANDARD2_0
int readByteCount;
#else
SynchronousAsyncResult<int> syncReadResult;
AsyncCallback readCallback;
TaskCompletionSource writeCompletion;
AsyncCallback writeCallback;
#endif
public MediationStream(TlsHandler owner)
{
this.owner = owner;
}
public int SourceReadableBytes => this.inputLength - this.inputOffset;
public void SetSource(byte[] source, int offset)
{
this.input = source;
this.inputStartOffset = offset;
this.inputOffset = 0;
this.inputLength = 0;
}
public void ResetSource()
{
this.input = null;
this.inputLength = 0;
}
public void ExpandSource(int count)
{
Contract.Assert(this.input != null);
this.inputLength += count;
ArraySegment<byte> sslBuffer = this.sslOwnedBuffer;
if (sslBuffer.Array == null)
{
// there is no pending read operation - keep for future
return;
}
this.sslOwnedBuffer = default(ArraySegment<byte>);
#if NETSTANDARD2_0
this.readByteCount = this.ReadFromInput(sslBuffer.Array, sslBuffer.Offset, sslBuffer.Count);
// hack: this tricks SslStream's continuation to run synchronously instead of dispatching to TP. Remove once Begin/EndRead are available.
new Task(
ms =>
{
var self = (MediationStream)ms;
TaskCompletionSource<int> p = self.readCompletionSource;
self.readCompletionSource = null;
p.TrySetResult(self.readByteCount);
},
this)
.RunSynchronously(TaskScheduler.Default);
#else
int read = this.ReadFromInput(sslBuffer.Array, sslBuffer.Offset, sslBuffer.Count);
TaskCompletionSource<int> promise = this.readCompletionSource;
this.readCompletionSource = null;
promise.TrySetResult(read);
AsyncCallback callback = this.readCallback;
this.readCallback = null;
callback?.Invoke(promise.Task);
#endif
}
#if NETSTANDARD2_0
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (this.SourceReadableBytes > 0)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer, offset, count);
return Task.FromResult(read);
}
Contract.Assert(this.sslOwnedBuffer.Array == null);
// take note of buffer - we will pass bytes there once available
this.sslOwnedBuffer = new ArraySegment<byte>(buffer, offset, count);
this.readCompletionSource = new TaskCompletionSource<int>();
return this.readCompletionSource.Task;
}
#else
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (this.SourceReadableBytes > 0)
{
// we have the bytes available upfront - write out synchronously
int read = this.ReadFromInput(buffer, offset, count);
var res = this.PrepareSyncReadResult(read, state);
callback?.Invoke(res);
return res;
}
Contract.Assert(this.sslOwnedBuffer.Array == null);
// take note of buffer - we will pass bytes there once available
this.sslOwnedBuffer = new ArraySegment<byte>(buffer, offset, count);
this.readCompletionSource = new TaskCompletionSource<int>(state);
this.readCallback = callback;
return this.readCompletionSource.Task;
}
public override int EndRead(IAsyncResult asyncResult)
{
SynchronousAsyncResult<int> syncResult = this.syncReadResult;
if (ReferenceEquals(asyncResult, syncResult))
{
return syncResult.Result;
}
Debug.Assert(this.readCompletionSource == null || this.readCompletionSource.Task == asyncResult);
Contract.Assert(!((Task<int>)asyncResult).IsCanceled);
try
{
return ((Task<int>)asyncResult).Result;
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw; // unreachable
}
}
IAsyncResult PrepareSyncReadResult(int readBytes, object state)
{
// it is safe to reuse sync result object as it can't lead to leak (no way to attach to it via handle)
SynchronousAsyncResult<int> result = this.syncReadResult ?? (this.syncReadResult = new SynchronousAsyncResult<int>());
result.Result = readBytes;
result.AsyncState = state;
return result;
}
#endif
public override void Write(byte[] buffer, int offset, int count) => this.owner.FinishWrap(buffer, offset, count);
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> this.owner.FinishWrapNonAppDataAsync(buffer, offset, count);
#if !NETSTANDARD2_0
static readonly Action<Task, object> WriteCompleteCallback = HandleChannelWriteComplete;
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
Task task = this.WriteAsync(buffer, offset, count);
switch (task.Status)
{
case TaskStatus.RanToCompletion:
// write+flush completed synchronously (and successfully)
var result = new SynchronousAsyncResult<int>();
result.AsyncState = state;
callback?.Invoke(result);
return result;
default:
if (callback != null || state != task.AsyncState)
{
Contract.Assert(this.writeCompletion == null);
this.writeCallback = callback;
var tcs = new TaskCompletionSource(state);
this.writeCompletion = tcs;
task.ContinueWith(WriteCompleteCallback, this, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
else
{
return task;
}
}
}
static void HandleChannelWriteComplete(Task writeTask, object state)
{
var self = (MediationStream)state;
AsyncCallback callback = self.writeCallback;
self.writeCallback = null;
var promise = self.writeCompletion;
self.writeCompletion = null;
switch (writeTask.Status)
{
case TaskStatus.RanToCompletion:
promise.TryComplete();
break;
case TaskStatus.Canceled:
promise.TrySetCanceled();
break;
case TaskStatus.Faulted:
promise.TrySetException(writeTask.Exception);
break;
default:
throw new ArgumentOutOfRangeException("Unexpected task status: " + writeTask.Status);
}
callback?.Invoke(promise.Task);
}
public override void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult is SynchronousAsyncResult<int>)
{
return;
}
try
{
((Task)asyncResult).Wait();
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw;
}
}
#endif
int ReadFromInput(byte[] destination, int destinationOffset, int destinationCapacity)
{
Contract.Assert(destination != null);
byte[] source = this.input;
int readableBytes = this.SourceReadableBytes;
int length = Math.Min(readableBytes, destinationCapacity);
Buffer.BlockCopy(source, this.inputStartOffset + this.inputOffset, destination, destinationOffset, length);
this.inputOffset += length;
return length;
}
public override void Flush()
{
// NOOP: called on SslStream.Close
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
TaskCompletionSource<int> p = this.readCompletionSource;
if (p != null)
{
this.readCompletionSource = null;
p.TrySetResult(0);
}
}
}
#region plumbing
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
#endregion
#region sync result
sealed class SynchronousAsyncResult<T> : IAsyncResult
{
public T Result { get; set; }
public bool IsCompleted => true;
public WaitHandle AsyncWaitHandle
{
get { throw new InvalidOperationException("Cannot wait on a synchronous result."); }
}
public object AsyncState { get; set; }
public bool CompletedSynchronously => true;
}
#endregion
}
}
[Flags]

Просмотреть файл

@ -53,12 +53,13 @@ namespace DotNetty.Handlers.Tls
/// The length of the encrypted packet that is included in the buffer. This will
/// return <c>-1</c> if the given <see cref="IByteBuffer"/> is not encrypted at all.
/// </returns>
public static int GetEncryptedPacketLength(IByteBuffer buffer, int offset)
public static int GetEncryptedPacketLength(IByteBuffer buffer, int offset, out byte contentType)
{
int packetLength = 0;
// SSLv3 or TLS - Check ContentType
switch (buffer.GetByte(offset))
contentType = buffer.GetByte(offset);
switch (contentType)
{
case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
case SSL_CONTENT_TYPE_ALERT:
@ -90,6 +91,11 @@ namespace DotNetty.Handlers.Tls
return packetLength;
}
public static int GetEncryptedPacketLength(IByteBuffer buffer, int offset)
{
return GetEncryptedPacketLength(buffer, offset, out _);
}
public static void NotifyHandshakeFailure(IChannelHandlerContext ctx, Exception cause)
{
// We have may haven written some parts of data before an exception was thrown so ensure we always flush.
@ -98,5 +104,23 @@ namespace DotNetty.Handlers.Tls
ctx.FireUserEventTriggered(new TlsHandshakeCompletionEvent(cause));
ctx.CloseAsync();
}
public static string FormatContentType(byte contentType)
{
switch (contentType)
{
case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
return nameof(SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC);
case SSL_CONTENT_TYPE_ALERT:
return nameof(SSL_CONTENT_TYPE_ALERT);
case SSL_CONTENT_TYPE_HANDSHAKE:
return nameof(SSL_CONTENT_TYPE_HANDSHAKE);
case SSL_CONTENT_TYPE_APPLICATION_DATA:
return nameof(SSL_CONTENT_TYPE_APPLICATION_DATA);
default:
// SSLv2 or bad data
return "non-ssl";
}
}
}
}

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?><Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Transport.Libuv</PackageId>
<Description>Libuv transport model in DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: libuv transport model Experimental</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>

Просмотреть файл

@ -19,6 +19,7 @@ namespace DotNetty.Transport.Libuv
using DotNetty.Common;
using DotNetty.Transport.Libuv.Native;
using Timer = Native.Timer;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
class LoopExecutor : AbstractScheduledEventExecutor
{

Просмотреть файл

@ -331,7 +331,7 @@ namespace DotNetty.Transport.Libuv.Native
{
Debug.Assert(handle != IntPtr.Zero);
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
int namelen = Marshal.SizeOf<sockaddr>();
#else
int namelen = Marshal.SizeOf(typeof(sockaddr));
@ -344,7 +344,7 @@ namespace DotNetty.Transport.Libuv.Native
{
Debug.Assert(handle != IntPtr.Zero);
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
int namelen = Marshal.SizeOf<sockaddr>();
#else
int namelen = Marshal.SizeOf(typeof(sockaddr));
@ -354,7 +354,7 @@ namespace DotNetty.Transport.Libuv.Native
return sockaddr.GetIPEndPoint();
}
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
internal static IntPtr Allocate(int size) => Marshal.AllocCoTaskMem(size);
internal static void FreeMemory(IntPtr ptr) => Marshal.FreeCoTaskMem(ptr);

Просмотреть файл

@ -41,7 +41,7 @@ namespace DotNetty.Transport.Libuv.Native
IntPtr socket = IntPtr.Zero;
NativeMethods.uv_fileno(handle.Handle, ref socket);
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
uint len = (uint)Marshal.SizeOf<FILE_COMPLETION_INFORMATION>();
#else
uint len = (uint)Marshal.SizeOf(typeof(FILE_COMPLETION_INFORMATION));

Просмотреть файл

@ -26,7 +26,7 @@ namespace DotNetty.Transport.Libuv.Native
static WriteRequest()
{
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
BufferSize = Marshal.SizeOf<uv_buf_t>();
#else
BufferSize = Marshal.SizeOf(typeof(uv_buf_t));

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Transport.Libuv
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Libuv.Native;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public abstract class NativeChannel : AbstractChannel
{

Просмотреть файл

@ -15,6 +15,7 @@ namespace DotNetty.Transport.Libuv
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Libuv.Native;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
sealed class WorkerEventLoop : LoopExecutor, IEventLoop
{

Просмотреть файл

@ -14,6 +14,7 @@ namespace DotNetty.Transport.Bootstrapping
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// This is a helper class that makes it easy to bootstrap an <see cref="IChannel"/>. It supports method-

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Transport.Bootstrapping
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// A <see cref="Bootstrap"/> that makes it easy to bootstrap an <see cref="IChannel"/> to use for clients.

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public abstract class AbstractChannel : DefaultAttributeMap, IChannel
{

Просмотреть файл

@ -14,6 +14,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
abstract class AbstractChannelHandlerContext : IChannelHandlerContext, IResourceLeakHint
{

Просмотреть файл

@ -11,6 +11,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// A queue of write operations which are pending for later execution. It also updates the

Просмотреть файл

@ -16,6 +16,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using ReferenceEqualityComparer = DotNetty.Common.Utilities.ReferenceEqualityComparer;
public class DefaultChannelPipeline : IChannelPipeline
{

Просмотреть файл

@ -14,7 +14,7 @@ namespace DotNetty.Transport.Channels.Embedded
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
public class EmbeddedChannel : AbstractChannel
public class EmbeddedChannel : AbstractChannel, IEmbeddedChannel
{
static readonly EndPoint LOCAL_ADDRESS = new EmbeddedSocketAddress();
static readonly EndPoint REMOTE_ADDRESS = new EmbeddedSocketAddress();

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Embedded
{
public interface IEmbeddedChannel : IChannel
{
bool WriteInbound(params object[] msgs);
bool WriteOutbound(params object[] msgs);
T ReadInbound<T>();
T ReadOutbound<T>();
bool Finish();
}
}

Просмотреть файл

@ -0,0 +1,468 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Embedded
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Net;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using DotNetty.Common;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
public class SingleThreadedEmbeddedChannel : AbstractChannel, IEmbeddedChannel
{
static readonly EndPoint LOCAL_ADDRESS = new EmbeddedSocketAddress();
static readonly EndPoint REMOTE_ADDRESS = new EmbeddedSocketAddress();
enum State
{
Open,
Active,
Closed
};
static readonly IChannelHandler[] EMPTY_HANDLERS = new IChannelHandler[0];
static readonly IInternalLogger logger = InternalLoggerFactory.GetInstance<EmbeddedChannel>();
static readonly ChannelMetadata METADATA_NO_DISCONNECT = new ChannelMetadata(false);
static readonly ChannelMetadata METADATA_DISCONNECT = new ChannelMetadata(true);
readonly IEventLoop loop = new SingleThreadEventLoop();
Queue<object> inboundMessages;
Queue<object> outboundMessages;
Exception lastException;
State state;
/// <summary>
/// Create a new instance with an empty pipeline.
/// </summary>
public SingleThreadedEmbeddedChannel(IEventLoop eventLoop = null)
: this(EmbeddedChannelId.Instance, eventLoop, EMPTY_HANDLERS)
{
}
/// <summary>
/// Create a new instance with an empty pipeline with the specified <see cref="IChannelId" />.
/// </summary>
/// <param name="channelId">The <see cref="IChannelId" /> of this channel. </param>
public SingleThreadedEmbeddedChannel(IChannelId channelId, IEventLoop eventLoop = null)
: this(channelId, eventLoop, EMPTY_HANDLERS)
{
}
/// <summary>
/// Create a new instance with the pipeline initialized with the specified handlers.
/// </summary>
/// <param name="handlers">
/// The <see cref="IChannelHandler" />s that will be added to the <see cref="IChannelPipeline" />
/// </param>
public SingleThreadedEmbeddedChannel(IEventLoop eventLoop = null, params IChannelHandler[] handlers)
: this(EmbeddedChannelId.Instance, eventLoop, handlers)
{
}
public SingleThreadedEmbeddedChannel(IChannelId id, IEventLoop eventLoop = null, params IChannelHandler[] handlers)
: this(id, false, eventLoop, handlers)
{
}
/// <summary>Create a new instance with the pipeline initialized with the specified handlers.</summary>
/// <param name="id">The <see cref="IChannelId" /> of this channel.</param>
/// <param name="hasDisconnect">
/// <c>false</c> if this <see cref="IChannel" /> will delegate <see cref="DisconnectAsync" />
/// to <see cref="CloseAsync" />, <c>true</c> otherwise.
/// </param>
/// <param name="handlers">
/// The <see cref="IChannelHandler" />s that will be added to the <see cref="IChannelPipeline" />
/// </param>
public SingleThreadedEmbeddedChannel(IChannelId id, bool hasDisconnect, IEventLoop eventLoop = null, params IChannelHandler[] handlers)
: this(id, hasDisconnect, true, eventLoop, handlers)
{ }
public SingleThreadedEmbeddedChannel(IChannelId id, bool hasDisconnect, bool register, IEventLoop eventLoop = null, params IChannelHandler[] handlers)
: base(null, id)
{
if (eventLoop != null)
{
this.loop = eventLoop;
}
this.Metadata = GetMetadata(hasDisconnect);
this.Configuration = new DefaultChannelConfiguration(this);
this.Setup(register, handlers);
}
public SingleThreadedEmbeddedChannel(IChannelId id, bool hasDisconnect, IChannelConfiguration config, IEventLoop eventLoop = null,
params IChannelHandler[] handlers)
: base(null, id)
{
Contract.Requires(config != null);
if (eventLoop != null)
{
this.loop = eventLoop;
}
this.Metadata = GetMetadata(hasDisconnect);
this.Configuration = config;
this.Setup(true, handlers);
}
static ChannelMetadata GetMetadata(bool hasDisconnect) => hasDisconnect ? METADATA_DISCONNECT : METADATA_NO_DISCONNECT;
void Setup(bool register, params IChannelHandler[] handlers)
{
Contract.Requires(handlers != null);
IChannelPipeline p = this.Pipeline;
p.AddLast(new ActionChannelInitializer<IChannel>(channel =>
{
IChannelPipeline pipeline = channel.Pipeline;
foreach (IChannelHandler h in handlers)
{
if (h == null)
{
break;
}
pipeline.AddLast(h);
}
}));
if (register)
{
Task future = this.loop.RegisterAsync(this);
future.GetAwaiter().GetResult();
Debug.Assert(future.IsCompleted);
}
}
public void Register()
{
Task future = this.loop.RegisterAsync(this);
// Debug.Assert(future.IsCompleted);
this.Pipeline.AddLast(new LastInboundHandler(this.InboundMessages, this.RecordException));
future.GetAwaiter().GetResult();
}
protected sealed override DefaultChannelPipeline NewChannelPipeline() => new SingleThreadedEmbeddedChannelPipeline(this);
public override ChannelMetadata Metadata { get; }
public override IChannelConfiguration Configuration { get; }
/// <summary>
/// Returns the <see cref="Queue{T}" /> which holds all of the <see cref="object" />s that
/// were received by this <see cref="IChannel" />.
/// </summary>
public Queue<object> InboundMessages => this.inboundMessages ?? (this.inboundMessages = new Queue<object>());
/// <summary>
/// Returns the <see cref="Queue{T}" /> which holds all of the <see cref="object" />s that
/// were written by this <see cref="IChannel" />.
/// </summary>
public Queue<object> OutboundMessages => this.outboundMessages ?? (this.outboundMessages = new Queue<object>());
/// <summary>
/// Return received data from this <see cref="IChannel"/>.
/// </summary>
public T ReadInbound<T>() => (T)Poll(this.inboundMessages);
/// <summary>
/// Read data from the outbound. This may return <c>null</c> if nothing is readable.
/// </summary>
public T ReadOutbound<T>() => (T)Poll(this.outboundMessages);
protected override EndPoint LocalAddressInternal => this.Active ? LOCAL_ADDRESS : null;
protected override EndPoint RemoteAddressInternal => this.Active ? REMOTE_ADDRESS : null;
protected override IChannelUnsafe NewUnsafe() => new DefaultUnsafe(this);
protected override bool IsCompatible(IEventLoop eventLoop) => true;
protected override void DoBind(EndPoint localAddress)
{
//NOOP
}
protected override void DoRegister() => this.state = State.Active;
protected override void DoDisconnect() => this.DoClose();
protected override void DoClose() => this.state = State.Closed;
protected override void DoBeginRead()
{
//NOOP
}
protected override void DoWrite(ChannelOutboundBuffer input)
{
for (;;)
{
object msg = input.Current;
if (msg == null)
{
break;
}
ReferenceCountUtil.Retain(msg);
this.OutboundMessages.Enqueue(msg);
input.Remove();
}
}
public override bool Open => this.state != State.Closed;
public override bool Active => this.state == State.Active;
/// <summary>
/// Write messages to the inbound of this <see cref="IChannel" />
/// </summary>
/// <param name="msgs">The messages to be written.</param>
/// <returns><c>true</c> if the write operation did add something to the inbound buffer</returns>
public bool WriteInbound(params object[] msgs)
{
this.EnsureOpen();
if (msgs.Length == 0)
{
return IsNotEmpty(this.inboundMessages);
}
IChannelPipeline p = this.Pipeline;
foreach (object m in msgs)
{
p.FireChannelRead(m);
}
p.FireChannelReadComplete();
this.CheckException();
return IsNotEmpty(this.inboundMessages);
}
/// <summary>
/// Write messages to the outbound of this <see cref="IChannel" />.
/// </summary>
/// <param name="msgs">The messages to be written.</param>
/// <returns><c>true</c> if the write operation did add something to the inbound buffer</returns>
public bool WriteOutbound(params object[] msgs)
{
this.EnsureOpen();
if (msgs.Length == 0)
{
return IsNotEmpty(this.outboundMessages);
}
ThreadLocalObjectList futures = ThreadLocalObjectList.NewInstance(msgs.Length);
foreach (object m in msgs)
{
if (m == null)
{
break;
}
futures.Add(this.WriteAsync(m));
}
this.Flush();
int size = futures.Count;
for (int i = 0; i < size; i++)
{
var future = (Task)futures[i];
if (future.IsCompleted)
{
this.RecordException(future);
}
else
{
// The write may be delayed to run later by runPendingTasks()
future.ContinueWith(t => this.RecordException(t));
}
}
futures.Return();
this.CheckException();
return IsNotEmpty(this.outboundMessages);
}
void RecordException(Task future)
{
switch (future.Status)
{
case TaskStatus.Canceled:
case TaskStatus.Faulted:
this.RecordException(future.Exception);
break;
default:
break;
}
}
void RecordException(Exception cause)
{
if (this.lastException == null)
{
this.lastException = cause;
}
else
{
logger.Warn("More than one exception was raised. " + "Will report only the first one and log others.", cause);
}
}
/// <summary>
/// Mark this <see cref="IChannel" /> as finished. Any further try to write data to it will fail.
/// </summary>
/// <returns>bufferReadable returns <c>true</c></returns>
public bool Finish() => this.Finish(false);
/// <summary>
/// Marks this <see cref="IChannel"/> as finished and releases all pending message in the inbound and outbound
/// buffer. Any futher try to write data to it will fail.
/// </summary>
/// <returns><c>true</c> if any of the used buffers has something left to read, otherwise <c>false</c>.</returns>
public bool FinishAndReleaseAll() => this.Finish(true);
/// <summary>
/// Marks this <see cref="IChannel"/> as finished. Any futher attempt to write data to it will fail.
/// </summary>
/// <param name="releaseAll">If <c>true</c>, all pending messages in the inbound and outbound buffer are released.</param>
/// <returns><c>true</c> if any of the used buffers has something left to read, otherwise <c>false</c>.</returns>
bool Finish(bool releaseAll)
{
this.CloseSafe();
try
{
this.CheckException();
return IsNotEmpty(this.inboundMessages) || IsNotEmpty(this.outboundMessages);
}
finally
{
if (releaseAll)
{
ReleaseAll(this.inboundMessages);
ReleaseAll(this.outboundMessages);
}
}
}
/// <summary>
/// Releases all buffered inbound messages.
/// </summary>
/// <returns><c>true</c> if any were in the inbound buffer, otherwise <c>false</c>.</returns>
public bool ReleaseInbound() => ReleaseAll(this.inboundMessages);
/// <summary>
/// Releases all buffered outbound messages.
/// </summary>
/// <returns><c>true</c> if any were in the outbound buffer, otherwise <c>false</c>.</returns>
public bool ReleaseOutbound() => ReleaseAll(this.outboundMessages);
static bool ReleaseAll(Queue<object> queue)
{
if (queue != null && queue.Count > 0)
{
for (;;)
{
if (queue.Count == 0)
{
break;
}
object msg = queue.Dequeue();
ReferenceCountUtil.Release(msg);
}
return true;
}
return false;
}
public override Task CloseAsync()
{
// We need to call RunPendingTasks() before calling super.CloseAsync() as there may be something in the queue
// that needs to be run before the actual close takes place.
Task future = base.CloseAsync();
return future;
}
public override Task DisconnectAsync()
{
Task future = base.DisconnectAsync();
return future;
}
static bool IsNotEmpty(Queue<object> queue) => queue != null && queue.Count > 0;
/// <summary>
/// Check to see if there was any <see cref="Exception" /> and rethrow if so.
/// </summary>
public void CheckException()
{
Exception e = this.lastException;
if (e == null)
{
return;
}
this.lastException = null;
ExceptionDispatchInfo.Capture(e).Throw();
}
/// <summary>
/// Ensure the <see cref="IChannel" /> is open and if not throw an exception.
/// </summary>
protected void EnsureOpen()
{
if (!this.Open)
{
this.RecordException(new ClosedChannelException());
this.CheckException();
}
}
static object Poll(Queue<object> queue) => IsNotEmpty(queue) ? queue.Dequeue() : null;
class DefaultUnsafe : AbstractUnsafe
{
public DefaultUnsafe(AbstractChannel channel)
: base(channel)
{
}
public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) => TaskEx.Completed;
}
internal sealed class LastInboundHandler : ChannelHandlerAdapter
{
readonly Queue<object> inboundMessages;
readonly Action<Exception> recordException;
public LastInboundHandler(Queue<object> inboundMessages, Action<Exception> recordException)
{
this.inboundMessages = inboundMessages;
this.recordException = recordException;
}
public override void ChannelRead(IChannelHandlerContext context, object message) => this.inboundMessages.Enqueue(message);
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) => this.recordException(exception);
}
sealed class SingleThreadedEmbeddedChannelPipeline : DefaultChannelPipeline
{
public SingleThreadedEmbeddedChannelPipeline(SingleThreadedEmbeddedChannel channel)
: base(channel)
{
}
protected override void OnUnhandledInboundException(Exception cause) => ((SingleThreadedEmbeddedChannel)this.Channel).RecordException(cause);
protected override void OnUnhandledInboundMessage(object msg) => ((SingleThreadedEmbeddedChannel)this.Channel).InboundMessages.Enqueue(msg);
}
}
}

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Transport.Channels.Local
using DotNetty.Common.Internal;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// A <see cref="IChannel"/> for the local transport.

Просмотреть файл

@ -11,6 +11,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// A queue of write operations which are pending for later execution. It also updates the writability of the

Просмотреть файл

@ -154,7 +154,7 @@ namespace DotNetty.Transport.Channels.Sockets
{
SocketChannelAsyncOperation operation = this.ReadOperation;
bool pending;
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
pending = this.Socket.ReceiveAsync(operation);
#else
if (ExecutionContext.IsFlowSuppressed())
@ -308,7 +308,7 @@ namespace DotNetty.Transport.Channels.Sockets
this.SetState(StateFlags.WriteScheduled);
bool pending;
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
pending = this.Socket.SendAsync(operation);
#else
if (ExecutionContext.IsFlowSuppressed())

Просмотреть файл

@ -12,6 +12,7 @@ namespace DotNetty.Transport.Channels.Sockets
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public abstract class AbstractSocketChannel : AbstractChannel
{

Просмотреть файл

@ -7,6 +7,7 @@ namespace DotNetty.Transport.Channels.Sockets
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using DotNetty.Common.Concurrency;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public interface IDatagramChannel : IChannel
{

Просмотреть файл

@ -16,6 +16,7 @@ namespace DotNetty.Transport.Channels.Sockets
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class SocketDatagramChannel : AbstractSocketMessageChannel, IDatagramChannel
{
@ -115,7 +116,7 @@ namespace DotNetty.Transport.Channels.Sockets
operation.SetBuffer(bytes.Array, bytes.Offset, bytes.Count);
bool pending;
#if NETSTANDARD2_0
#if NETSTANDARD2_0 || NETCOREAPP3_1_OR_GREATER || NET5_0_OR_GREATER
pending = this.Socket.ReceiveFromAsync(operation);
#else
if (ExecutionContext.IsFlowSuppressed())

Просмотреть файл

@ -10,6 +10,7 @@ namespace DotNetty.Transport.Channels.Sockets
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Common.Concurrency;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
/// <summary>
/// <see cref="ISocketChannel" /> which uses Socket-based implementation.

Просмотреть файл

@ -7,6 +7,7 @@ namespace DotNetty.Transport.Channels
using System.Threading.Tasks;
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
static class Util
{

Просмотреть файл

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="NuGet">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net472;net5;net6</TargetFrameworks>
<IsPackable>true</IsPackable>
<PackageId>DotNetty.Transport</PackageId>
<Description>Transport model in DotNetty</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<AssemblyTitle>DotNetty: transport model</AssemblyTitle>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.7.2</VersionPrefix>
<VersionPrefix>0.7.3</VersionPrefix>
<Authors>Microsoft</Authors>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Просмотреть файл

@ -7,7 +7,7 @@ using System.Reflection;
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("DotNetty")]
[assembly: AssemblyVersion("0.7.2")]
[assembly: AssemblyFileVersion("0.7.2")]
[assembly: AssemblyVersion("0.7.3")]
[assembly: AssemblyFileVersion("0.7.3")]
[assembly: AssemblyCopyright("(c) Microsoft 2015 - 2021")]

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -17,6 +17,7 @@ namespace DotNetty.Codecs.Http.Tests
using Xunit;
using HttpVersion = DotNetty.Codecs.Http.HttpVersion;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public sealed class HttpClientCodecTest
{

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Codecs.Http.Tests
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Embedded;
using Xunit;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class HttpServerUpgradeHandlerTest
{

Просмотреть файл

@ -12,6 +12,7 @@ namespace DotNetty.Codecs.Http.Tests.WebSockets
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Embedded;
using Xunit;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class WebSocketHandshakeHandOverTest
{

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Common.Tests.Concurrency
using DotNetty.Tests.Common;
using Xunit;
using Xunit.Abstractions;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class SingleThreadEventExecutorTests : TestBase
{

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -11,7 +11,7 @@ namespace DotNetty.Handlers.Tests
class AsIsWriteStrategy : IWriteStrategy
{
public Task WriteToChannelAsync(EmbeddedChannel channel, ArraySegment<byte> input)
public Task WriteToChannelAsync(IEmbeddedChannel channel, ArraySegment<byte> input)
{
channel.WriteInbound(Unpooled.WrappedBuffer(input.Array, input.Offset, input.Count));
return TaskEx.Completed;

Просмотреть файл

@ -14,7 +14,7 @@ namespace DotNetty.Handlers.Tests
readonly TimeSpan timeWindow;
readonly bool forceSizing;
IByteBuffer pendingBuffer;
EmbeddedChannel channel;
IEmbeddedChannel channel;
public BatchingWriteStrategy(int maxBatchSize, TimeSpan timeWindow, bool forceSizing)
{
@ -23,7 +23,7 @@ namespace DotNetty.Handlers.Tests
this.forceSizing = forceSizing;
}
public async Task WriteToChannelAsync(EmbeddedChannel ch, ArraySegment<byte> input)
public async Task WriteToChannelAsync(IEmbeddedChannel ch, ArraySegment<byte> input)
{
this.channel = ch;

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -9,6 +9,6 @@ namespace DotNetty.Handlers.Tests
public interface IWriteStrategy
{
Task WriteToChannelAsync(EmbeddedChannel channel, ArraySegment<byte> input);
Task WriteToChannelAsync(IEmbeddedChannel channel, ArraySegment<byte> input);
}
}

Просмотреть файл

@ -72,13 +72,13 @@ namespace DotNetty.Handlers.Tests
this.Output.WriteLine($"protocol: {protocol}");
this.Output.WriteLine($"targetHost: {targetHost}");
var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));
var executor = new SingleThreadEventLoop("test executor", TimeSpan.FromMilliseconds(10));
try
{
var writeTasks = new List<Task>();
var pair = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, protocol, writeTasks, targetHost).WithTimeout(TimeSpan.FromSeconds(10));
EmbeddedChannel ch = pair.Item1;
IEmbeddedChannel ch = pair.Item1;
SslStream driverStream = pair.Item2;
int randomSeed = Environment.TickCount;
@ -139,13 +139,13 @@ namespace DotNetty.Handlers.Tests
this.Output.WriteLine($"targetHost: {targetHost}");
var writeStrategy = new AsIsWriteStrategy();
var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));
var executor = new SingleThreadEventLoop("test executor", TimeSpan.FromMilliseconds(10));
try
{
var writeTasks = new List<Task>();
var pair = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, protocol, writeTasks, targetHost);
EmbeddedChannel ch = pair.Item1;
IEmbeddedChannel ch = pair.Item1;
SslStream driverStream = pair.Item2;
int randomSeed = Environment.TickCount;
@ -189,7 +189,7 @@ namespace DotNetty.Handlers.Tests
}
}
static async Task<Tuple<EmbeddedChannel, SslStream>> SetupStreamAndChannelAsync(bool isClient, IEventExecutor executor, IWriteStrategy writeStrategy, SslProtocols protocol, List<Task> writeTasks, string targetHost)
static async Task<Tuple<IEmbeddedChannel, SslStream>> SetupStreamAndChannelAsync(bool isClient, IEventLoop executor, IWriteStrategy writeStrategy, SslProtocols protocol, List<Task> writeTasks, string targetHost)
{
IChannelHandler tlsHandler = isClient ?
(IChannelHandler)new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) =>
@ -199,13 +199,19 @@ namespace DotNetty.Handlers.Tests
}), new ClientTlsSettings(protocol, false, new List<X509Certificate>(), targetHost)) :
new SniHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ServerTlsSniSettings(CertificateSelector));
//var ch = new EmbeddedChannel(new LoggingHandler("BEFORE"), tlsHandler, new LoggingHandler("AFTER"));
var ch = new EmbeddedChannel(tlsHandler);
#if NET5_0_OR_GREATER
IEmbeddedChannel ch = new SingleThreadedEmbeddedChannel(executor, tlsHandler);
#else
IEmbeddedChannel ch = new EmbeddedChannel(tlsHandler);
#endif
if (!isClient)
{
// check if in the beginning snihandler exists in the pipeline, but not tls handler
Assert.NotNull(ch.Pipeline.Get<SniHandler>());
Assert.Null(ch.Pipeline.Get<TlsHandler>());
await AssertEx.EventuallyAsync(
() => ch.Pipeline.Get<SniHandler>() != null && ch.Pipeline.Get<TlsHandler>() == null,
TimeSpan.FromMilliseconds(10),
TimeSpan.FromSeconds(5)
);
}
IByteBuffer readResultBuffer = Unpooled.Buffer(4 * 1024);

Просмотреть файл

@ -69,7 +69,6 @@ namespace DotNetty.Handlers.Tests
select new object[] { frameLengths, isClient, writeStrategyFactory(), protocol.Item1, protocol.Item2 };
}
[Theory]
[MemberData(nameof(GetTlsReadTestData))]
public async Task TlsRead(int[] frameLengths, bool isClient, IWriteStrategy writeStrategy, SslProtocols serverProtocol, SslProtocols clientProtocol)
@ -80,15 +79,15 @@ namespace DotNetty.Handlers.Tests
this.Output.WriteLine($"serverProtocol: {serverProtocol}");
this.Output.WriteLine($"clientProtocol: {clientProtocol}");
var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));
var executor = new SingleThreadEventLoop("test executor", TimeSpan.FromMilliseconds(10));
try
{
var writeTasks = new List<Task>();
var pair = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, serverProtocol, clientProtocol, writeTasks).WithTimeout(TimeSpan.FromSeconds(10));
EmbeddedChannel ch = pair.Item1;
IEmbeddedChannel ch = pair.Item1;
SslStream driverStream = pair.Item2;
int randomSeed = Environment.TickCount;
var random = new Random(randomSeed);
IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
@ -101,6 +100,7 @@ namespace DotNetty.Handlers.Tests
}
await Task.WhenAll(writeTasks).WithTimeout(TimeSpan.FromSeconds(5));
IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
await ReadOutboundAsync(async () => ch.ReadInbound<IByteBuffer>(), expectedBuffer.ReadableBytes, finalReadBuffer, TestTimeout);
bool isEqual = ByteBufferUtil.Equals(expectedBuffer, finalReadBuffer);
if (!isEqual)
@ -160,15 +160,15 @@ namespace DotNetty.Handlers.Tests
var writeStrategy = new AsIsWriteStrategy();
this.Output.WriteLine($"writeStrategy: {writeStrategy}");
var executor = new SingleThreadEventExecutor("test executor", TimeSpan.FromMilliseconds(10));
var executor = new SingleThreadEventLoop("test executor", TimeSpan.FromMilliseconds(10));
try
{
var writeTasks = new List<Task>();
var pair = await SetupStreamAndChannelAsync(isClient, executor, writeStrategy, serverProtocol, clientProtocol, writeTasks);
EmbeddedChannel ch = pair.Item1;
IEmbeddedChannel ch = pair.Item1;
SslStream driverStream = pair.Item2;
int randomSeed = Environment.TickCount;
var random = new Random(randomSeed);
IByteBuffer expectedBuffer = Unpooled.Buffer(16 * 1024);
@ -182,7 +182,7 @@ namespace DotNetty.Handlers.Tests
return (object)Unpooled.WrappedBuffer(data);
}).ToArray());
}
IByteBuffer finalReadBuffer = Unpooled.Buffer(16 * 1024);
var readBuffer = new byte[16 * 1024 * 10];
await ReadOutboundAsync(
@ -206,7 +206,7 @@ namespace DotNetty.Handlers.Tests
}
}
static async Task<Tuple<EmbeddedChannel, SslStream>> SetupStreamAndChannelAsync(bool isClient, IEventExecutor executor, IWriteStrategy writeStrategy, SslProtocols serverProtocol, SslProtocols clientProtocol, List<Task> writeTasks)
static async Task<Tuple<IEmbeddedChannel, SslStream>> SetupStreamAndChannelAsync(bool isClient, IEventLoop executor, IWriteStrategy writeStrategy, SslProtocols serverProtocol, SslProtocols clientProtocol, List<Task> writeTasks)
{
X509Certificate2 tlsCertificate = TestResourceHelper.GetTestCertificate();
string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false);
@ -214,7 +214,12 @@ namespace DotNetty.Handlers.Tests
new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(clientProtocol, false, new List<X509Certificate>(), targetHost)) :
new TlsHandler(new ServerTlsSettings(tlsCertificate, false, false, serverProtocol));
//var ch = new EmbeddedChannel(new LoggingHandler("BEFORE"), tlsHandler, new LoggingHandler("AFTER"));
var ch = new EmbeddedChannel(tlsHandler);
#if NET5_0_OR_GREATER
IEmbeddedChannel ch = new SingleThreadedEmbeddedChannel(executor, tlsHandler);
#else
IEmbeddedChannel ch = new EmbeddedChannel(tlsHandler);
#endif
IByteBuffer readResultBuffer = Unpooled.Buffer(4 * 1024);
Func<ArraySegment<byte>, Task<int>> readDataFunc = async output =>
@ -228,21 +233,40 @@ namespace DotNetty.Handlers.Tests
if (readResultBuffer.ReadableBytes < output.Count)
{
if (ch.Active)
await ReadOutboundAsync(async () => ch.ReadOutbound<IByteBuffer>(), output.Count - readResultBuffer.ReadableBytes, readResultBuffer, TestTimeout, readResultBuffer.ReadableBytes != 0 ? 0 : 1);
{
await ReadOutboundAsync(
async () => ch.ReadOutbound<IByteBuffer>(),
output.Count - readResultBuffer.ReadableBytes,
readResultBuffer,
TestTimeout,
readResultBuffer.ReadableBytes != 0 ? 0 : 1
);
}
}
int read = Math.Min(output.Count, readResultBuffer.ReadableBytes);
readResultBuffer.ReadBytes(output.Array, output.Offset, read);
return read;
};
var mediationStream = new MediationStream(readDataFunc, input =>
{
Task task = executor.SubmitAsync(() => writeStrategy.WriteToChannelAsync(ch, input)).Unwrap();
writeTasks.Add(task);
return task;
}, () =>
{
ch.CloseAsync();
});
var mediationStream = new MediationStream(
output =>
{
Task<int> task = executor.SubmitAsync(
() => readDataFunc(output)
).Unwrap();
return task;
},
input =>
{
Task task = executor.SubmitAsync(
() => writeStrategy.WriteToChannelAsync(ch, input)
).Unwrap();
writeTasks.Add(task);
return task;
},
() =>
{
ch.CloseAsync();
});
var driverStream = new SslStream(mediationStream, true, (_1, _2, _3, _4) => true);
if (isClient)

Просмотреть файл

@ -2,10 +2,12 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -2,9 +2,11 @@
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="..\..\shared\dotnetty.com.pfx" />

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />

Просмотреть файл

@ -23,6 +23,7 @@ namespace DotNetty.Tests.End2End
using DotNetty.Transport.Channels.Sockets;
using Xunit;
using Xunit.Abstractions;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public class End2EndTests : TestBase
{

Просмотреть файл

@ -13,6 +13,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class BufReleaseTests : IDisposable

Просмотреть файл

@ -14,6 +14,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class CompositeBufferGatheringWriteTests : IDisposable

Просмотреть файл

@ -14,6 +14,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class DetectPeerCloseWithoutReadTests : IDisposable

Просмотреть файл

@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net472;net5;net6</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyOriginatorKeyFile>../../DotNetty.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<Configurations>Debug;Release;Package</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Просмотреть файл

@ -14,6 +14,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit.Abstractions;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class EchoTests : IDisposable

Просмотреть файл

@ -11,6 +11,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using Xunit.Abstractions;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
public sealed class EventLoopTests : TestBase, IDisposable
{

Просмотреть файл

@ -15,6 +15,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class ExceptionHandlingTests : IDisposable

Просмотреть файл

@ -15,6 +15,7 @@ namespace DotNetty.Transport.Libuv.Tests
using Xunit;
using static TestUtil;
using TaskCompletionSource = DotNetty.Common.Concurrency.TaskCompletionSource;
[Collection(LibuvTransport)]
public sealed class ReadPendingTests : IDisposable

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше