Commit Graph

6514 Commits

Author SHA1 Message Date
Robert.Panzer
01c3fd3ace Add support for byte order to LengthFieldPrepender
Motivation:

While the LengthFieldBasedFrameDecoder supports a byte order the LengthFieldPrepender does not.
That means that I can simply add a LengthFieldBasedFrameDecoder with ByteOrder.LITTLE_ENDIAN to my pipeline
but have to write my own Encoder to write length fields in little endian byte order.

Modifications:

Added a constructor that takes a byte order and all other parameters.
All other constructors delegate to this one with ByteOrder.BIG_ENDIAN.
LengthFieldPrepender.encode() uses this byte order to write the length field.

Result:

LengthFieldPrepender will write the length field in the defined byte order.
2015-03-13 19:30:49 +01:00
Norman Maurer
6954f034fd First load RuntimeException to prevent segfault on error
Motivation:

When an error happens during loading the native library it may try to generate a new RuntimeException before the RuntimeException is loaded.

Modifications:

- Load RuntimeException as first

Result:

No more segfaults possible
2015-03-13 18:28:32 +01:00
Norman Maurer
fadbf7df52 Respect -Djava.net.preferIPv4Stack when using epoll transport
Motivation:

On a system where ipv4 and ipv6 are supported a user may want to use -Djava.net.preferIPv4Stack=true to restrict it to use ipv4 only.
This is currently ignored with the epoll transport.

Modifications:

Respect java.net.preferIPv4Stack system property.

Result:

-Djava.net.preferIPv4Stack=true will have the effect the user is looking for.
2015-03-11 02:49:33 +01:00
Norman Maurer
6b67f8ec81 Fix possible AttributeMap corruption on double removal
Motivation:

When remove0() is called multiple times for an DefaultAttribute it can cause corruption of the internal linked-list structure.

Modifications:

- Ensure remove0() can not cause corruption by null out prev and next references.

Result:

No more corruption possible
2015-03-10 05:07:35 +01:00
Trustin Lee
54293003ef Add a new constructor without handler parameter to TrafficCounter
Related: #3476

Motivation:

Some users use TrafficCounter for other uses than we originally
intended, such as implementing their own traffic shaper.  In such a
case, a user does not want to specify an AbstractTrafficShapingHandler.

Modifications:

- Add a new constructor that does not require an
  AbstractTrafficShapingHandler, so that a user can use it without it.
- Simplify TrafficMonitoringTask
- Javadoc cleanup

Result:

We open the possibility of using TrafficCounter for other purposes than
just using it with AbstractTrafficShapingHandler.  Eventually, we could
generalize it a little bit more, so that we can potentially use it for
other uses.
2015-03-10 11:26:41 +09:00
Leo Gomes
96cb879054 Add unit to maxContentLength javadoc of HttpObjectAggregator
Motivation:
Not knowing which unit is used for the maxContentLength of the HttpObjectAggregator when reading the Javadoc is annoying and can be a source of bugs.

Modifications:
Added the mention "in bytes"

Result:
Javadoc is clear.
2015-03-05 20:54:52 +01:00
Trustin Lee
5d15e18cbf Fix SocketException in NioSocketChannelUnsafe.closeExecutor()
Related: #3464

Motivation:

When a connection attempt is failed,
NioSocketChannelUnsafe.closeExecutor() triggers a SocketException,
suppressing the channelUnregistered() event.

Modification:

Do not attempt to get SO_LINGER value when a socket is not open yet.

Result:

One less bug
2015-03-05 15:17:43 +09:00
Norman Maurer
6880e27ce9 [#3463] EpollSocketChannel.localAddress() returns always null if Native.connect() was not able to connect directly
Motivation:

Due a a regression that was introduced by b898bdd we failed to set the localAddress if the connect did not success directly.

Modifications:

Correct set localAddress in doConnect(...)

Result:

Be able to get the localAddress in all cases.
2015-03-04 20:02:37 +01:00
Trustin Lee
05333862ba Fix inspector warnings 2015-03-04 17:25:53 +09:00
Trustin Lee
2c14406b55 Fix header and initial line length counting
Related: #3445

Motivation:

HttpObjectDecoder.HeaderParser does not reset its counter (the size
field) when it failed to find the end of line.  If a header is split
into multiple fragments, the counter is increased as many times as the
number of fragments, resulting an unexpected TooLongFrameException.

Modifications:

- Add test cases that reproduces the problem
- Reset the HeaderParser.size field when no EOL is found.

Result:

One less bug
2015-03-04 17:19:31 +09:00
Leo Gomes
2cc7466266 Updates the javadoc of Unpooled to remove mention to methods it does not provide
Motivation:

`Unpooled` javadoc's mentioned the generation of hex dump and swapping an integer's byte order,
which are actually provided by `ByteBufUtil`.

Modifications:

 Sentence moved to `ByteBufUtil` javadoc.

Result:

`Unpooled` javadoc is correct.
2015-03-04 12:03:50 +09:00
Norman Maurer
37264bb72b [maven-release-plugin] prepare for next development iteration 2015-03-02 01:31:30 -05:00
Norman Maurer
0dbc96cffd [maven-release-plugin] prepare release netty-4.0.26.Final 2015-03-02 01:30:58 -05:00
Norman Maurer
5ebc998ca2 Fix version number 2015-03-02 06:40:02 +01:00
Norman Maurer
f8e158a39f [#3457] Proper fix for IllegalStateException caused by closed file descriptor / channel
Motivation:

During 6b941e9bdb I introduced a regression that could cause an IllegalStateException.
A non-proper fix was commited as part of #3443. This commit add a proper fix.

Modifications:

Remove FileDescriptor.INVALID and add FileDescriptor.isOpen() as replacement. Once FileDescriptor.close() is called isOpen() will return false.

Result:

No more IllegalStateException caused by a close channel.
2015-03-01 19:36:31 +01:00
Norman Maurer
e99d89c04d [maven-release-plugin] rollback the release of netty-4.0.26.Final 2015-02-28 21:28:06 +01:00
Norman Maurer
b86e2e6ac0 [maven-release-plugin] prepare release netty-4.0.26.Final 2015-02-28 13:55:01 -05:00
Norman Maurer
7ae44f8910 [#3066] EpollDatagramChannel never calls fireChannelActive() after connect()
Motivation:

EpollDragramChannel never calls fireChannelActive after connect() which is a bug.

Modifications:

Correctly call fireChannelActive if needed

Result:

Correct behaviour
2015-02-28 15:52:10 +01:00
Norman Maurer
b54857b9a0 Pass struct's per pointer to eliminate memory copy.
Motivation:

Before struct's were passed per value and not pointer. This did enforce a memory copy which is not needed.

Modifications:

- Use "const struct....*" as replacement

Result:

No more unnecessary memory copies
2015-02-27 20:58:03 +01:00
Norman Maurer
6293b0579c Fix byte order when retrieve address from filedescriptor
Motivation:

When create address from filedescriptor we may use incorrect byte order and so end up with an incorrect InetAddress.

Modification:

Not manually shift bytes

Result:

Correct address in all cases.
2015-02-27 20:54:03 +01:00
jongyoon lim
269695d043 typo_fix in the comment 2015-02-25 20:30:49 +01:00
Norman Maurer
42677f82a6 Fix regression introduced by 20e32f62ec
Motivation:

Because of a regression sometimes accept could produce an IllegalArgumentException

Modifications:

Correctly respect offset when decode port and scope id.

Result:

No more IllegalArgumentException
2015-02-24 11:03:02 +01:00
Norman Maurer
960a486f13 [#3443] Fix IllegalStateException which could be triggered when the channel goes inactive during the eventloop processing
Motivation:

This is a regression that was introduced as part of 6b941e9bdb. The regression could produce an "infinity" triggering of IllegalStateException if a channel goes inactive while process the events for it.

Modifications:

Correctly check if the channel is still active before trigger the callbacks.

Result:

No more IllegalStateException
2015-02-23 19:10:33 +01:00
Norman Maurer
c21067aab6 Directly receive remote address when call accept(...)
Motivation:

There is a small race in the native transport where an accept(...) may success but a later try to obtain the remote address from the fd may fail is the fd is already closed.

Modifications:

Let accept(...) directly set the remote address.

Result:

No more race possible.
2015-02-23 14:54:27 +01:00
Norman Maurer
556a3d5980 Correctly handle autoRead == false when epoll LT is used
Motivation:

When epoll LT is used and autoRead == false when entering epollIn() we need to return without reading any data.

Modifications:

Correctly respect autoRead == false if using epoll LT.

Result:

Consistent and correct behaviour.
2015-02-23 07:38:14 +01:00
Norman Maurer
29a5bc9fb6 [#3438] Throw pre-instanced IOException on connection reset
Motivation:

In the native transport we should throw a pre-instanced IOException on connection reset while reading.

Modifications:

Correctly throw pre-instanced IOException when ECONNRESET is received

Result:

Less overhead on connection reset
2015-02-21 21:31:05 +01:00
Norman Maurer
6950bfb5d8 Allow to use EmbeddedChannel.schedule*(...)
Motivation:

At the moment when EmbeddedChannel is used and a ChannelHandler tries to schedule and task it will throw an UnsupportedOperationException. This makes it impossible to test these handlers or even reuse them with EmbeddedChannel.

Modifications:

- Factor out reusable scheduling code into AbstractSchedulingEventExecutor
- Let EmbeddedEventLoop and SingleThreadEventExecutor extend AbstractSchedulingEventExecutor
- add EmbbededChannel.runScheduledPendingTasks() which allows to run all scheduled tasks that are ready

Result:

Embeddedchannel is now usable even with ChannelHandler that try to schedule tasks.
2015-02-20 09:53:25 +01:00
jongyoon lim
a2f77e743e removed an unnecessary local variable for consistency 2015-02-18 20:13:05 +01:00
Daniel Bevenius
a9794342e1 When null origin is supported then credentials header must not be set.
Motivation:
Currently CORS can be configured to support a 'null' origin, which can
be set by a browser if a resources is loaded from the local file system.
When this is done 'Access-Control-Allow-Origin' will be set to "*" (any
origin). There is also a configuration option to allow credentials being
sent from the client (cookies, basic HTTP Authentication, client side
SSL). This is indicated by the response header
'Access-Control-Allow-Credentials' being set to true. When this is set
to true, the "*" origin is not valid as the value of
'Access-Control-Allow-Origin' and a browser will reject the request:
http://www.w3.org/TR/cors/#resource-requests

Modifications:
Updated CorsHandler's setAllowCredentials to check the origin and if it
is "*" then it will not add the 'Access-Control-Allow-Credentials'
header.

Result:
Is is possible to have a client send a 'null' origin, and at the same
time have configured the CORS to support that and to allow credentials
in that combination.

Conflicts:
	codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java
2015-02-18 16:20:20 +01:00
Robert Varga
2aad79fcca Add a pax-exam based OSGi test suite
Motivation:

Release 4.0.25 was not usable in OSGi environments due to a simple typo.
An automated test could have caught the problem even before it was
committed.

Modifications:

This patch introduces a new artifact, osgitests, which pulls in all
production artifacts (which we want to be checked for OSGi compliance).
It contains only a single unit test, which runs a pax-exam container
with felix OSGi.

At initialization time, it scans all the artifact's dependencies,
looking for things belonging to io.netty group. The container is
configured to deploy those artifacts as bundles and fail if any bundle
is found to be unresolved. It performs a final check to see if any
bundles were tested this way, to make sure the mechanism is not
completely broken.

We are using wrappedBundle(), as two of our third-party dependencies do
not export packages correctly -- this masks the problem, assuming that
whoever deploys our artifacts depending on them will figure out how to
OSGify them.

Result:

Simple typos and other bundle manifest errors should be caught during
test phase of every build.
2015-02-18 15:56:27 +01:00
Norman Maurer
47f095856c Allow to get existing ChannelOption / AttributeKey from String
Motivation:

We should allow to get a ChannelOption/AttributeKey from a String. This will make it a lot easier to make use of configuration files in applications.

Modifications:

- Add exists(...), newInstance(...) method to ChannelOption and AttributeKey and alter valueOf(...) to return an existing instance for a String or create one.
- Add unit tests.

Result:

Much more flexible usage of ChannelOption and AttributeKey.
2015-02-18 09:12:43 +01:00
Norman Maurer
027d868438 Move generic unix classes/interfaces out of epoll package
Motivation:

As we plan to have other native transports soon (like a kqueue transport) we should move unix classes/interfaces out of the epoll package so we
introduce other implementations without breaking stuff before the next stable release.

Modifications:

Create a new io.netty.channel.unix package and move stuff over there.

Result:

Possible to introduce other native impls beside epoll.
2015-02-17 17:55:12 +01:00
Cristian
c03f57e9bd Fixed ServerBootstrap#group(EventLoopGroup, EventLoopGroup) javadoc 2015-02-16 07:39:25 +01:00
Cristian
37cca81f1c Avoid unnecessary call to ByteBuf.isReadable() from ByteToMessageDecoder
Motivation:

This will avoid one unncessary method invokation which will slightly improve performance.

Modifications:

Instead of calling isReadable we just check for the value of readableBytes()

Result:

Nothing functionally speaking change.
2015-02-16 07:26:25 +01:00
Fabian Lange
489f2e1d75 Fixed broken optional OSGi Import-Package header (#3424). 2015-02-13 20:44:06 +01:00
Norman Maurer
5f71b6dc54 Ensure CompositeByteBuf.addComponent* handles buffer in consistent way and not causes leaks
Motivation:

At the moment we have two problems:
 - CompositeByteBuf.addComponent(...) will not add the supplied buffer to the CompositeByteBuf if its empty, which means it will not be released on CompositeByteBuf.release() call. This is a problem as a user will expect everything added will be released (the user not know we not added it).
 - CompositeByteBuf.addComponents(...) will either add no buffers if none is readable and so has the same problem as addComponent(...) or directly release the ByteBuf if at least one ByteBuf is readable. Again this gives inconsistent handling and may lead to memory leaks.

Modifications:

 - Always add the buffer to the CompositeByteBuf and so release it on release call.

Result:

Consistent handling and no buffer leaks.
2015-02-12 16:09:24 +01:00
Norman Maurer
9d697d7a9a Allow to create Epoll*Channel from FileDescriptor
Motivation:

Sometimes it's useful to be able to create a Epoll*Channel from an existing file descriptor. This is especially helpful if you integrade some c/jni code.

Modifications:

- Add extra constructor to Epoll*Channel implementations that take a FileDescriptor as an argument
- Make Rename EpollFileDescriptor to NativeFileDescriptor and make it public
- Also ensure we obtain the correct remote/local address when create a Channel from a FileDescriptor

Result:

It's now possible to create a FileDescriptor and instance a Epoll*Channel via it.
2015-02-09 09:56:10 +01:00
Trustin Lee
5fca3de098 Add another test case for channelReadComplete() suppression
Related commit:
- a41b46ff43

Motivation:

We need a test case for the commit above.
2015-02-09 16:29:02 +09:00
Norman Maurer
f7ccdd5d3b Various performance optimizations in OpenSslEngine
Motivation:

There are various places in OpenSslEngine wher we can do performance optimizations.

Modifications:

- Reduce JNI calls when possible
- Detect finished handshake as soon as possible
- Eliminate double calculations
- wrap multiple ByteBuffer if possible in a loop

Result:

Better performance
2015-02-09 06:20:09 +01:00
Norman Maurer
33f75d3740 Not execute shutdownOutput(...) and close(...) in the EventLoop if SO_LINGER is used.
Motivation:

If SO_LINGER is used shutdownOutput() and close() syscalls will block until either all data was send or until the timeout exceed. This is a problem when we try to execute them on the EventLoop as this means the EventLoop may be blocked and so can not process any other I/O.

Modifications:

- Add AbstractUnsafe.closeExecutor() which returns null by default and use this Executor for close if not null.
- Override the closeExecutor() in NioSocketChannel and EpollSocketChannel and return GlobalEventExecutor.INSTANCE if getSoLinger() > 0
- use closeExecutor() in shutdownInput(...) in NioSocketChannel and EpollSocketChannel

 Result:

No more blocking of the EventLoop if SO_LINGER is used and shutdownOutput() or close() is called.
2015-02-08 20:11:15 +01:00
Norman Maurer
6231113c38 Give compiler hint about inline functions
Motivation:

Some of the methods are frequently called and so should be inlined if possible.

Modifications:

Give the compiler a hint that we want to inline these methods.

Result:

Better performance if inlined.
2015-02-08 13:57:13 +01:00
Norman Maurer
adeb950c91 Cleanup code. Part of [#3398] 2015-02-08 13:04:12 +01:00
Norman Maurer
795de8a590 Add workaround for bug in older linux kernels handling epoll_wait(...)
Motivation:

Older linux kernels have problems handling a large value for epoll_wait(...) and so wait for ever.

Modifications:

Adjust timeout on the fly if a too big value is passed in.

Result:

Correctly works also on older kernels.
2015-02-08 11:35:50 +01:00
Norman Maurer
4d0eeb0dcc Respect ChannelConfig.getWriteSpinCount() when using epoll transport
Motivation:

The writeSpinCount was ignored in the epoll transport and it just kept on trying writing. This could cause unnessary cpu spinning if a slow remote peer was reading the data very very slow.

Modification:

- Correctly take writeSpinCount into account when writing.

Result:

Less cpu spinning when writing to a slow remote peer.
2015-02-08 11:07:46 +01:00
Trustin Lee
10a5635acb Reorder PlatformDependent.isRoot() check
Motivation:

isRoot() is an expensive operation. We should avoid calling it if
possible.

Modifications:

Move the isRoot() checks to the end of the 'if' block, so that isRoot()
is evaluated only when really necessary.

Result:

isRoot() is evaluated only when SO_BROADCAST is set and the bind address
is anylocal address.
2015-02-08 11:59:56 +09:00
Norman Maurer
3ca6e4bd54 Correctly set EPOLLRDHUP for all stream channels.
Motivation:

Fix regression introduced by 585ce1593f, which missed to set EPOLLRDHUP for all stream channels.

Modifications:

Correctly set EPOLLRDHUP for all stream channels in the AbstractEpollStreamChannel constructor.

Result:

No more test failures in EpollDomain*Channel tests.
2015-02-07 21:29:46 +01:00
Trustin Lee
a41b46ff43 Do not suppress channelReadComplete() when a handler was just added
Related:
- 8b2fb2b985

Motivation:

The commit mentioned above introduced a regression where
channelReadComplete() event is swallowed by a handler which was added
dynamically.

Modifications:

Do not suppress channelReadComplete() if the current handler's
channelRead() method was not invoked at all, so that a just-added
handler does not suppress channelReadComplete().

Result:

Regression is gone, and channelReadComplete() is invoked when necessary.
2015-02-07 23:18:46 +09:00
Norman Maurer
585ce1593f Faster event processing when epoll transport is used
Motivation:

Before we used a long[] to store the ready events, this had a few problems and limitations:
 - An extra loop was needed to translate between epoll_event and our long
 - JNI may need to do extra memory copy if the JVM not supports pinning
 - More branches

Modifications:

- Introduce a EpollEventArray which allows to directly write in a struct epoll_event* and pass it to epoll_wait.

Result:

Better speed when using native transport, as shown in the benchmark.

Before:
[xxx@xxx wrk]$ ./wrk -H 'Connection: keep-alive' -d 120 -c 256 -t 16 -s scripts/pipeline-many.lua  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
 16 threads and 256 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency    14.56ms    8.64ms 117.15ms   80.58%
   Req/Sec   286.17k    38.71k  421.48k    68.17%
 546324329 requests in 2.00m, 73.78GB read
Requests/sec: 4553438.39
Transfer/sec:    629.66MB

After:
[xxx@xxx wrk]$ ./wrk -H 'Connection: keep-alive' -d 120 -c 256 -t 16 -s scripts/pipeline-many.lua  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
 16 threads and 256 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency    14.12ms    8.69ms 100.40ms   83.08%
   Req/Sec   294.79k    40.23k  472.70k    66.75%
 555997226 requests in 2.00m, 75.08GB read
Requests/sec: 4634343.40
Transfer/sec:    640.85MB
2015-02-07 08:22:26 +01:00
Trustin Lee
8b2fb2b985 Ensure channelReadComplete() is called only when necessary
Related:
- 375b9e1307

Motivation:

Even if a handler called ctx.fireChannelReadComplete(), the next handler
should not get its channelReadComplete() invoked if fireChannelRead()
was not invoked before.

Modifications:

- Ensure channelReadComplete() is invoked only when the handler of the
  current context actually produced a message, because otherwise there's
  no point of triggering channelReadComplete().
  i.e. channelReadComplete() must follow channelRead().
- Fix a bug where ctx.read() was not called if the handler of the
  current context did not produce any message, making the connection
  stall. Read the new comment for more information.

Result:

- channelReadComplete() is invoked only when it makes sense.
- No stale connection
2015-02-07 16:12:43 +09:00
Norman Maurer
1c01dd1efc Log only on debug log level in OpenSslEngine
Motivation:

At the moment we log priming read and handshake errors via info log level and still throw a SSLException that contains the error. We should only log with debug level to generate less noise.

Modifications:

Change logging to debug level.

Result:

Less noise .
2015-02-07 06:01:41 +01:00